package com.huilian.iotbox.admin.wap.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.huilian.iotbox.admin.wap.dao.*;
import com.huilian.iotbox.admin.wap.service.*;
import com.huilian.iotbox.data.common.ServerResponse;
import com.huilian.iotbox.data.dto.*;
import com.huilian.iotbox.data.enums.*;
import com.huilian.iotbox.data.exception.SysException;
import com.huilian.iotbox.data.po.StatsStoreDetail;
import com.huilian.iotbox.data.service.StatsStoreDetailCommonService;
import com.huilian.iotbox.data.utils.CopyPropertiesUtils;
import com.huilian.iotbox.data.utils.DateTimeUtils;
import com.huilian.iotbox.data.vo.*;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * @author 谢洛涛
 * @date 2021/5/8 10:53
 */
@Slf4j
@Service
public class StatsStoreServiceImpl implements StatsStoreService {
    @Autowired
    private OrderService orderService;
    @Autowired
    private StatsUserDao statsUserDao;
    @Autowired
    private StatsStoreDao statsStoreDao;
    @Autowired
    private MerchantStoreService merchantStoreService;
    @Autowired
    private StatsStoreDetailCommonService statsStoreDetailCommonService;
    @Resource
    private DeviceService deviceService;
    @Resource
    private MemberDao memberDao;
    @Autowired
    private MemberStoreBalanceService memberStoreBalanceService;
    @Resource
    private StatsPackageUserDao statsPackageUserDao;
    @Resource
    private StatsPackageStoreDao statsPackageStoreDao;
    @Autowired
    private ThreadPoolExecutor executor;
    @Autowired
    private StatsStoreService statsStoreService;
    @Autowired
    private StatsDeviceService statsDeviceService;

    @Getter
    public enum BranchIdEnum {
        ONLINE_REVENUE(0, "扫码支付"),
        CASH_INCOME(1, "现金收入"),
        ACTIVITY_REVENUE(2, "活动收入"),
        DOU_YIN(3,"抖音核销收入"),
        MEI_TUAN(4,"美团核销收入"),
        ;

        //枚举值所包含的属性
        private Integer id;
        private String desc;

        //构造方法
        BranchIdEnum(Integer id, String desc) {
            this.id = id;
            this.desc = desc;
        }
    }
    @Override
    public List<StatsStoreVo> findStoreStatisticsList(StatsUserVo statsUserVo) {
        return statsStoreDao.findStoreStatisticsList(statsUserVo);
    }

    @Override
    public StatsStoreVo findStoreStatistics(StatsStoreDto statsStoreDto) {
        statsStoreDto.setStatsType(StatsTypeEnum.statsUser.getCode());
        if (statsStoreDto.getMchStoreId() != null) {
            String startTime = null;
            String endTime = null;
            if (statsStoreDto.getType() == 1) {
                //获取昨天 00：00：00
                startTime = DateTimeUtils.getTodayStartTime();
                //获取昨天 23：59：59
                endTime = DateTimeUtils.getTodayEndTime();
            } else {
                //本月开始时间 00：00：00
                startTime = DateTimeUtils.getMonthFirstDayTime();
                //本月结算时间 23：59：59
                endTime = DateTimeUtils.getMonthLastDayTime();
            }
            statsStoreDto.setStartTime(startTime);
            statsStoreDto.setEndTime(endTime);
            statsStoreDto.setConsumeRecordTypeIdArray(statsStoreDto.getInsertCoinConsumeRecordTypeIdArray());
            StatsStoreVo statsStoreVo = statsStoreDao.findOrderStatistics(statsStoreDto);
            statsStoreVo.setDateStr(DateTimeUtils.getCurrTime());

            return statsStoreVo;
        } else {
            return statsStoreDao.findStoreStatistics(statsStoreDto);
        }
    }

    @Override
    public List<StatsStoreVo> findOrderStatisticsList(StatsUserVo statsUserVo) {
        return statsStoreDao.findOrderStatisticsList(statsUserVo);
    }

    @Override
    public List<StatsStoreVo> findByDateStore(StatsUserDto statsUserDto) {
        return statsStoreDao.findByDateStore(statsUserDto);
    }

    @Override
    public BigDecimal findThisMonthTurnover(StatsUserDto statsUserDto) {
        statsUserDto.setStartDateStr(DateTimeUtils.getMonthFirstDay());
        statsUserDto.setEndDateStr(DateTimeUtils.getMonthLastDay());
        statsUserDto.setStatsType(StatsTypeEnum.statsUser.getCode());
        return statsStoreDao.findThisMonthTurnover(statsUserDto);
    }


    /**
     * 场地分析-公众号H5
     *
     * @param statsStoreDto
     * @return
     */
    @Override
    public ServerResponse findAllStoreStatisticsByUserIdAndDateTime(StatsStoreDto statsStoreDto) {

        if (StringUtils.isEmpty(statsStoreDto.getDateType())) {
            return ServerResponse.createByErrorMessage("请选择日期时间段");
        } else if (StringUtils.isEmpty(statsStoreDto.getStartDateStr())) {
            return ServerResponse.createByErrorMessage("缺少开始日期");
        } else if (StringUtils.isEmpty(statsStoreDto.getEndDateStr())) {
            return ServerResponse.createByErrorMessage("缺少结束日期");
        }

        String error = "error";
        String result = Optional.ofNullable(statsStoreDto)
                .map(statsStoreDto1 -> statsStoreDto.getDateType())
                .map(statsStoreDto1 -> statsStoreDto.getStartDateStr())
                .map(statsStoreDto1 -> statsStoreDto.getEndDateStr())
                .orElse("error");

        if (error.equals(result)) {
            return ServerResponse.createByErrorMessage("缺少参数");
        }


        /**
         * 1、主账号登录，查所有场地
         * 2、子账号登录，查分配到的场地
         */
        List<Integer> storeIdList;
        if (RoleEnum.SUB_ACCOUNT.getRoleId().equals(statsStoreDto.getUserInfo().getRoleId())) {
            // 统计子账号管理的场地
            storeIdList = statsStoreDto.getUserInfo().getStoreIdList();
        } else {
            storeIdList = Arrays.asList(merchantStoreService.findAllMerchantStoreIdByUserId(statsStoreDto.getUserInfo()));
        }

        if (!StringUtils.isEmpty(statsStoreDto.getMerchantStoreIdStr())) {
            String[] s = statsStoreDto.getMerchantStoreIdStr().split("_");

            Integer[] merchantStoreIdArray = new Integer[s.length];
            for (int i = 0; i < s.length; i++) {
                Integer merchantStoreId = Integer.valueOf(s[i]);
                if (storeIdList.contains(merchantStoreId)) {
                    merchantStoreIdArray[i] = merchantStoreId;
                }
            }

            if (merchantStoreIdArray.length > 0) {
                storeIdList = Arrays.asList(merchantStoreIdArray);
            }
        }

        if (storeIdList.size() == 0) {
            return ServerResponse.createByErrorMessage("该管理账号下暂无店铺");
        }

        MerchantStoreDto merchantStoreDto = new MerchantStoreDto();
        merchantStoreDto.setIdList(storeIdList);
        List<MerchantStoreVo> merchantStoreVoList = merchantStoreService.findAllMerchantStoreByListId(merchantStoreDto);

        String currentDateYMD = DateTimeUtils.getCurrTime();

        // 当天的实时统计数据
        List<StatsStoreVo> todayStatsStoreVoList = new ArrayList<>();
        Map<Integer, StatsStoreVo> todayStatsStoreVoMap = new HashMap<>();


        /**
         * dateType:
         * 0：自定义（可能包含今天）
         * 1：今天
         * 2：昨天
         * 3：本月（包含今天）
         * 4：上月
         * 5：今年（包含今天）
         * 6：自定义（可能包含今天）
         *
         *
         */

        StatsUserDto statsUserDto = CopyPropertiesUtils.CopyProperties(statsStoreDto, StatsUserDto.class);
        List<Integer> dateTypeList = new ArrayList<>();
        dateTypeList.add(0);
        dateTypeList.add(1);
        dateTypeList.add(3);
        dateTypeList.add(5);
        dateTypeList.add(6);

        // 可能包含当天的数据
        if (dateTypeList.contains(statsStoreDto.getDateType()) && statsUserDto.getEndDateStr().equals(currentDateYMD)) {
            statsStoreDto.setStartTime(DateTimeUtils.getTodayStartTime());
            statsStoreDto.setEndTime(DateTimeUtils.getTodayEndTime());

            StatsStoreVo statsStoreVo = null;
            for (int i = 0; i < merchantStoreVoList.size(); i++) {
                Integer mchStoreId = merchantStoreVoList.get(i).getId();




                // 当天单个场地订单数据
                statsStoreDto.setMchStoreId(mchStoreId);
                statsStoreVo = statsStoreDao.findOrderStatistics(statsStoreDto);


                statsStoreVo.setMchStoreId(mchStoreId);
                statsStoreVo.setDateStr(currentDateYMD);
                statsStoreVo.setTurnoverOnLine(statsStoreVo.getWxMoney().add(statsStoreVo.getAliMoney()));
                statsStoreVo.setTurnoverOffline(statsStoreVo.getCashMoney());

                todayStatsStoreVoList.add(statsStoreVo);
            }

            if (todayStatsStoreVoList.size() > 0) {
                todayStatsStoreVoMap = todayStatsStoreVoList.stream().collect(Collectors.toMap(StatsStoreVo::getMchStoreId, a -> a, (k1, k2) -> k1));
            }
        }

        for (int i = 0; i < merchantStoreVoList.size(); i++) {

            StatsStoreDto s = new StatsStoreDto();
            s.setStatsType(1);
            s.setType(1);
            s.setStartDateStr(statsStoreDto.getStartDateStr());
            s.setEndDateStr(statsStoreDto.getEndDateStr());
            s.setMchStoreId(merchantStoreVoList.get(i).getId());
            StatsStoreVo statsStoreVo = statsStoreDao.getStoreStatisticsByMchStoreId(s);

            StatsStoreVo statsStoreVoByToDay = todayStatsStoreVoMap.get(merchantStoreVoList.get(i).getId());
            if (StringUtils.isEmpty(statsStoreVoByToDay)) {
                statsStoreVoByToDay = new StatsStoreVo();
                statsStoreVoByToDay.setTurnover(BigDecimal.ZERO);
                statsStoreVoByToDay.setTurnoverOnLine(BigDecimal.ZERO);
                statsStoreVoByToDay.setTurnoverOffline(BigDecimal.ZERO);

                // 总投币数、线上投币总数、线下投币总数
                statsStoreVoByToDay.setInsertCoinOnLine(0);
                statsStoreVoByToDay.setInsertCoinOffline(0);
                statsStoreVoByToDay.setInsertCoinTotal(0);
                statsStoreVoByToDay.setConsumeRecordCount(0);

                // 总出礼数、总出礼成本、出礼率
                statsStoreVoByToDay.setGiftConsume(0);
                statsStoreVoByToDay.setGiftCost(BigDecimal.ZERO);
                statsStoreVoByToDay.setGiftOutRate(BigDecimal.ZERO);
            }

            if (dateTypeList.contains(statsStoreDto.getDateType())) {

                // 总营业额、线上支付总额、现金支付总额
                merchantStoreVoList.get(i).setTurnover(statsStoreVo.getTurnover().add(statsStoreVoByToDay.getTurnover()));
                merchantStoreVoList.get(i).setTurnoverOnLine(statsStoreVo.getTurnoverOnLine().add(statsStoreVoByToDay.getTurnoverOnLine()));
                merchantStoreVoList.get(i).setTurnoverOffline(statsStoreVo.getTurnoverOffline().add(statsStoreVoByToDay.getTurnoverOffline()));

                // 总投币数、线上投币总数、线下投币总数
                merchantStoreVoList.get(i).setInsertCoinOnLine(statsStoreVo.getInsertCoinOnLine() + statsStoreVoByToDay.getInsertCoinOnLine());
                merchantStoreVoList.get(i).setInsertCoinOffline(statsStoreVo.getInsertCoinOffline() + statsStoreVoByToDay.getInsertCoinOffline());
                merchantStoreVoList.get(i).setInsertCoinTotal(merchantStoreVoList.get(i).getInsertCoinOnLine() + merchantStoreVoList.get(i).getInsertCoinOffline());

                // 总出礼数、总出礼成本、出礼率
                merchantStoreVoList.get(i).setGiftConsume(statsStoreVo.getGiftConsume() + statsStoreVoByToDay.getGiftConsume());
                merchantStoreVoList.get(i).setGiftCost(statsStoreVo.getGiftCost().add(statsStoreVoByToDay.getGiftCost()));

                Integer consumeCount = statsStoreVoByToDay.getConsumeRecordCount() + statsStoreVo.getConsumeRecordCount();
                Integer tuiLiIncrementTotal = merchantStoreVoList.get(i).getGiftConsume();
                BigDecimal rate = BigDecimal.ZERO;
                if (consumeCount != 0) {
                    rate = BigDecimal.valueOf(tuiLiIncrementTotal).divide(new BigDecimal(String.valueOf(consumeCount)), 4, BigDecimal.ROUND_HALF_UP);
                } else if (consumeCount == 0 && tuiLiIncrementTotal.compareTo(0) == 1) {
                    // 投币次数为0，但有出礼
                    rate = BigDecimal.valueOf(1);
                }
                BigDecimal percentage = rate.multiply(new BigDecimal("100"));
                merchantStoreVoList.get(i).setGiftOutRate(percentage);
            } else {
                // 总营业额、线上支付总额、现金支付总额
                merchantStoreVoList.get(i).setTurnover(statsStoreVoByToDay.getTurnover().add(statsStoreVo.getTurnover()));
                merchantStoreVoList.get(i).setTurnoverOnLine(statsStoreVoByToDay.getTurnoverOnLine().add(statsStoreVo.getTurnoverOnLine()));
                merchantStoreVoList.get(i).setTurnoverOffline(statsStoreVoByToDay.getTurnoverOffline().add(statsStoreVo.getTurnoverOffline()));

                // 总投币数、线上投币总数、线下投币总数
                merchantStoreVoList.get(i).setInsertCoinOnLine(statsStoreVoByToDay.getInsertCoinOnLine() + statsStoreVo.getInsertCoinOnLine());
                merchantStoreVoList.get(i).setInsertCoinOffline(statsStoreVoByToDay.getInsertCoinOffline() + statsStoreVo.getInsertCoinOffline());
                merchantStoreVoList.get(i).setInsertCoinTotal(statsStoreVo.getInsertCoinOnLine() + statsStoreVo.getInsertCoinOffline());

                // 总出礼数、总出礼成本、出礼率
                merchantStoreVoList.get(i).setGiftConsume(statsStoreVoByToDay.getGiftConsume() + statsStoreVo.getGiftConsume());
                merchantStoreVoList.get(i).setGiftCost(statsStoreVoByToDay.getGiftCost().add(statsStoreVo.getGiftCost()));

                Integer consumeCount = statsStoreVoByToDay.getConsumeRecordCount() + statsStoreVo.getConsumeRecordCount();
                Integer tuiLiIncrementTotal = statsStoreVoByToDay.getGiftConsume() + statsStoreVo.getGiftConsume();
                BigDecimal rate = BigDecimal.ZERO;
                if (consumeCount != 0) {
                    rate = BigDecimal.valueOf(tuiLiIncrementTotal).divide(new BigDecimal(String.valueOf(consumeCount)), 4, BigDecimal.ROUND_HALF_UP);
                } else if (consumeCount == 0 && tuiLiIncrementTotal.compareTo(0) == 1) {
                    // 投币次数为0，但有出礼
                    rate = BigDecimal.valueOf(1);
                }
                BigDecimal percentage = rate.multiply(new BigDecimal("100"));

                merchantStoreVoList.get(i).setGiftOutRate(percentage);
            }
            merchantStoreVoList.get(i).setMchStoreId(merchantStoreVoList.get(i).getId());
        }

        // 营收排序
        merchantStoreVoList = merchantStoreVoList.stream().sorted((item1, item2) -> {
            if (statsStoreDto.getTurnoverSort()) {
                return item1.getTurnover().compareTo(item2.getTurnover());
            } else {
                return item2.getTurnover().compareTo(item1.getTurnover());
            }
        }).collect(Collectors.toList());


        //总营业额
        BigDecimal turnover = BigDecimal.ZERO;
        //线上投币
        Integer insertCoinOnLine = 0;
        //线下投币
        Integer insertCoinOffline = 0;
        //礼品消耗数
        Integer giftConsume = 0;
        for (int i = 0; i < merchantStoreVoList.size(); i++) {
            turnover = turnover.add(merchantStoreVoList.get(i).getTurnover());
            insertCoinOnLine = insertCoinOnLine + merchantStoreVoList.get(i).getInsertCoinOnLine();
            insertCoinOffline = insertCoinOffline + merchantStoreVoList.get(i).getInsertCoinOffline();
            giftConsume = giftConsume + merchantStoreVoList.get(i).getGiftConsume();
        }

        StatsStoreVo statsStoreVo = new StatsStoreVo();
        statsStoreVo.setMerchantStoreVoList(merchantStoreVoList);
        statsStoreVo.setTurnover(turnover);
        statsStoreVo.setInsertCoinOnLine(insertCoinOnLine);
        statsStoreVo.setInsertCoinOffline(insertCoinOffline);
        statsStoreVo.setGiftConsume(giftConsume);


        return ServerResponse.createBySuccess(statsStoreVo);
    }


    /**
     * 场地分析-小程序
     *
     * @param statsStoreDto
     * @return
     */
    @Override
    public ServerResponse findStatsStoreByApplet(StatsStoreDto statsStoreDto) {
        if (StringUtils.isEmpty(statsStoreDto.getDateType())) {
            return ServerResponse.createByErrorMessage("请选择日期时间段");
        } else if (StringUtils.isEmpty(statsStoreDto.getStartDateStr())) {
            return ServerResponse.createByErrorMessage("缺少开始日期");
        } else if (StringUtils.isEmpty(statsStoreDto.getEndDateStr())) {
            return ServerResponse.createByErrorMessage("缺少结束日期");
        }

        String error = "error";
        String result = Optional.ofNullable(statsStoreDto)
                .map(statsStoreDto1 -> statsStoreDto.getDateType())
                .map(statsStoreDto1 -> statsStoreDto.getStartDateStr())
                .map(statsStoreDto1 -> statsStoreDto.getEndDateStr())
                .orElse("error");

        if (error.equals(result)) {
            return ServerResponse.createByErrorMessage("缺少参数");
        }


        /**
         * 1、主账号登录，查所有场地
         * 2、子账号登录，查分配到的场地
         */
        List<Integer> storeIdList;
        if (RoleEnum.SUB_ACCOUNT.getRoleId().equals(statsStoreDto.getUserInfo().getRoleId())) {
            // 统计子账号管理的场地
            storeIdList = statsStoreDto.getUserInfo().getStoreIdList();
        } else {
            storeIdList = Arrays.asList(merchantStoreService.findAllMerchantStoreIdByUserId(statsStoreDto.getUserInfo()));
        }

        if (!StringUtils.isEmpty(statsStoreDto.getMerchantStoreIdStr())) {
            String[] s = statsStoreDto.getMerchantStoreIdStr().split("_");

            Integer[] merchantStoreIdArray = new Integer[s.length];
            for (int i = 0; i < s.length; i++) {
                Integer merchantStoreId = Integer.valueOf(s[i]);
                if (storeIdList.contains(merchantStoreId)) {
                    merchantStoreIdArray[i] = merchantStoreId;
                }
            }

            if (merchantStoreIdArray.length > 0) {
                storeIdList = Arrays.asList(merchantStoreIdArray);
            }
            System.out.println(storeIdList);
        }

        if (storeIdList.size() == 0) {
            return ServerResponse.createByErrorMessage("该管理账号下暂无店铺");
        }

        MerchantStoreDto merchantStoreDto = new MerchantStoreDto();
        merchantStoreDto.setIdList(storeIdList);
        List<MerchantStoreVo> merchantStoreVoList = merchantStoreService.findAllMerchantStoreByListId(merchantStoreDto);

        String currentDateYMD = DateTimeUtils.getCurrTime();

        // 当天的实时统计数据
        List<StatsStoreVo> todayStatsStoreVoList = new ArrayList<>();
        Map<Integer, StatsStoreVo> todayStatsStoreVoMap = new HashMap<>();


        /**
         * dateType:
         * 1：今天（包含今天）
         * 2：昨天
         * 3：本月（包含今天）
         * 4：上月
         * 5：今年（包含今天）
         */

        StatsUserDto statsUserDto = CopyPropertiesUtils.CopyProperties(statsStoreDto, StatsUserDto.class);
        List<Integer> dateTypeList = new ArrayList<>();
        dateTypeList.add(1);
        dateTypeList.add(3);
        dateTypeList.add(5);

        // 可能包含当天的数据
        if (dateTypeList.contains(statsStoreDto.getDateType()) && statsUserDto.getEndDateStr().equals(currentDateYMD)) {
            // 当天开始时间
            final String todayStartTime = DateTimeUtils.getTodayStartTime();
            // 当天结束时间
            final String todayEndTime = DateTimeUtils.getTodayEndTime();

            statsStoreDto.setStartTime(todayStartTime);
            statsStoreDto.setEndTime(todayEndTime);

            StatsStoreVo statsStoreVo = null;
            for (int i = 0; i < merchantStoreVoList.size(); i++) {
                Integer mchStoreId = merchantStoreVoList.get(i).getId();



                // 当天单个场地订单数据
                statsStoreDto.setMchStoreId(mchStoreId);
                statsStoreVo = statsStoreDao.findOrderStatistics(statsStoreDto);


                // 纸钞数据
                StatsStoreVo sStore = new StatsStoreVo();
                sStore.setOneYuanDenomination(0);
                sStore.setFiveYuanDenomination(0);
                sStore.setTenYuanDenomination(0);
                sStore.setTwentyYuanDenomination(0);
                sStore.setFiftyYuanDenomination(0);
                sStore.setOneHundredYuanDenomination(0);
                this.statsStoreDenomination(new Integer[]{mchStoreId}, todayStartTime, todayEndTime, sStore);

                statsStoreVo.setMchStoreId(mchStoreId);
                statsStoreVo.setDateStr(currentDateYMD);
                statsStoreVo.setTurnoverOnLine(statsStoreVo.getWxMoney().add(statsStoreVo.getAliMoney()));
                statsStoreVo.setTurnoverOffline(statsStoreVo.getCashMoney());
                statsStoreVo.setOneYuanDenomination(sStore.getOneYuanDenomination());
                statsStoreVo.setFiveYuanDenomination(sStore.getFiveYuanDenomination());
                statsStoreVo.setTenYuanDenomination(sStore.getTenYuanDenomination());
                statsStoreVo.setTwentyYuanDenomination(sStore.getTwentyYuanDenomination());
                statsStoreVo.setFiftyYuanDenomination(sStore.getFiftyYuanDenomination());
                statsStoreVo.setOneHundredYuanDenomination(sStore.getOneHundredYuanDenomination());

                todayStatsStoreVoList.add(statsStoreVo);
            }

            if (todayStatsStoreVoList.size() > 0) {
                todayStatsStoreVoMap = todayStatsStoreVoList.stream().collect(Collectors.toMap(StatsStoreVo::getMchStoreId, a -> a, (k1, k2) -> k1));
            }
        }

        for (int i = 0; i < merchantStoreVoList.size(); i++) {

            StatsStoreDto s = new StatsStoreDto();
            s.setStatsType(1);
            s.setType(1);
            s.setStartDateStr(statsStoreDto.getStartDateStr());
            s.setEndDateStr(statsStoreDto.getEndDateStr());
            s.setMchStoreId(merchantStoreVoList.get(i).getId());
            StatsStoreVo statsStoreVo = statsStoreDao.getStoreStatisticsByMchStoreId(s);


            if (dateTypeList.contains(statsStoreDto.getDateType())) {
                // 包含当天的数据，就要加上今天的数据
                StatsStoreVo statsStoreVoByToDay = todayStatsStoreVoMap.get(merchantStoreVoList.get(i).getId());
                if (StringUtils.isEmpty(statsStoreVoByToDay)) {
                    statsStoreVoByToDay = new StatsStoreVo();
                    statsStoreVoByToDay.setTurnover(BigDecimal.ZERO);
                    statsStoreVoByToDay.setTurnoverOnLine(BigDecimal.ZERO);
                    statsStoreVoByToDay.setTurnoverOffline(BigDecimal.ZERO);

                    // 总投币数、线上投币总数、线下投币总数
                    statsStoreVoByToDay.setInsertCoinOnLine(0);
                    statsStoreVoByToDay.setInsertCoinOffline(0);
                    statsStoreVoByToDay.setInsertCoinTotal(0);
                    statsStoreVoByToDay.setConsumeRecordCount(0);

                    // 总兑币机出币、卡劵核销出币、会员取币出币
                    statsStoreVoByToDay.setOutCoinTotal(0);
                    statsStoreVoByToDay.setFetchMemberOutCoinTotal(0);

                    // 总出礼数、总出礼成本、出礼率
                    statsStoreVoByToDay.setGiftConsume(0);
                    statsStoreVoByToDay.setGiftCost(BigDecimal.ZERO);
                    statsStoreVoByToDay.setGiftOutRate(BigDecimal.ZERO);

                    statsStoreVoByToDay.setOneYuanDenomination(0);
                    statsStoreVoByToDay.setFiveYuanDenomination(0);
                    statsStoreVoByToDay.setTenYuanDenomination(0);
                    statsStoreVoByToDay.setTwentyYuanDenomination(0);
                    statsStoreVoByToDay.setFiftyYuanDenomination(0);
                    statsStoreVoByToDay.setOneHundredYuanDenomination(0);
                }

                // 总营业额、线上支付总额、现金支付总额
                merchantStoreVoList.get(i).setTurnover(statsStoreVo.getTurnover().add(statsStoreVoByToDay.getTurnover()));
                merchantStoreVoList.get(i).setTurnoverOnLine(statsStoreVo.getTurnoverOnLine().add(statsStoreVoByToDay.getTurnoverOnLine()));
                merchantStoreVoList.get(i).setTurnoverOffline(statsStoreVo.getTurnoverOffline().add(statsStoreVoByToDay.getTurnoverOffline()));

                // 总投币数、线上投币总数、线下投币总数
                merchantStoreVoList.get(i).setInsertCoinOnLine(statsStoreVo.getInsertCoinOnLine() + statsStoreVoByToDay.getInsertCoinOnLine());
                merchantStoreVoList.get(i).setInsertCoinOffline(statsStoreVo.getInsertCoinOffline() + statsStoreVoByToDay.getInsertCoinOffline());
                merchantStoreVoList.get(i).setInsertCoinTotal(merchantStoreVoList.get(i).getInsertCoinOnLine() + merchantStoreVoList.get(i).getInsertCoinOffline());

                // 总兑币机出币
                merchantStoreVoList.get(i).setOutCoinTotal(statsStoreVo.getOutCoinTotal() + statsStoreVoByToDay.getOutCoinTotal());
                merchantStoreVoList.get(i).setFetchMemberOutCoinTotal(statsStoreVo.getFetchMemberOutCoinTotal() + statsStoreVoByToDay.getFetchMemberOutCoinTotal());

                // 总出礼数、总出礼成本、出礼率
                merchantStoreVoList.get(i).setGiftConsume(statsStoreVo.getGiftConsume() + statsStoreVoByToDay.getGiftConsume());
                merchantStoreVoList.get(i).setGiftCost(statsStoreVo.getGiftCost().add(statsStoreVoByToDay.getGiftCost()));

                Integer consumeCount = statsStoreVoByToDay.getConsumeRecordCount() + statsStoreVo.getConsumeRecordCount();
                Integer tuiLiIncrementTotal = merchantStoreVoList.get(i).getGiftConsume();
                BigDecimal rate = BigDecimal.ZERO;
                if (consumeCount != 0) {
                    rate = BigDecimal.valueOf(tuiLiIncrementTotal).divide(new BigDecimal(String.valueOf(consumeCount)), 4, BigDecimal.ROUND_HALF_UP);
                } else if (consumeCount == 0 && tuiLiIncrementTotal.compareTo(0) == 1) {
                    // 投币次数为0，但有出礼
                    rate = BigDecimal.valueOf(1);
                }
                BigDecimal percentage = rate.multiply(new BigDecimal("100"));
                merchantStoreVoList.get(i).setGiftOutRate(percentage);

                merchantStoreVoList.get(i).setOneYuanDenomination(statsStoreVo.getOneYuanDenomination() + statsStoreVoByToDay.getOneYuanDenomination());
                merchantStoreVoList.get(i).setFiveYuanDenomination(statsStoreVo.getFiveYuanDenomination() + statsStoreVoByToDay.getFiveYuanDenomination());
                merchantStoreVoList.get(i).setTenYuanDenomination(statsStoreVo.getTenYuanDenomination() + statsStoreVoByToDay.getTenYuanDenomination());
                merchantStoreVoList.get(i).setTwentyYuanDenomination(statsStoreVo.getTwentyYuanDenomination() + statsStoreVoByToDay.getTwentyYuanDenomination());
                merchantStoreVoList.get(i).setFiftyYuanDenomination(statsStoreVo.getFiftyYuanDenomination() + statsStoreVoByToDay.getFiftyYuanDenomination());
                merchantStoreVoList.get(i).setOneHundredYuanDenomination(statsStoreVo.getOneHundredYuanDenomination() + statsStoreVoByToDay.getOneHundredYuanDenomination());
            } else {
                // 没有包含今天的数据

                // 总营业额、线上支付总额、现金支付总额
                merchantStoreVoList.get(i).setTurnover(BigDecimal.ZERO);
                merchantStoreVoList.get(i).setTurnoverOnLine(BigDecimal.ZERO);
                merchantStoreVoList.get(i).setTurnoverOffline(BigDecimal.ZERO);

                // 总投币数、线上投币总数、线下投币总数
                merchantStoreVoList.get(i).setInsertCoinOnLine(0);
                merchantStoreVoList.get(i).setInsertCoinOffline(0);
                merchantStoreVoList.get(i).setInsertCoinTotal(0);
                merchantStoreVoList.get(i).setConsumeRecordCount(0);

                // 总兑币机出币
                merchantStoreVoList.get(i).setOutCoinTotal(0);
                merchantStoreVoList.get(i).setFetchMemberOutCoinTotal(0);

                // 总出礼数、总出礼成本、出礼率
                merchantStoreVoList.get(i).setGiftConsume(0);
                merchantStoreVoList.get(i).setGiftCost(BigDecimal.ZERO);
                merchantStoreVoList.get(i).setGiftOutRate(BigDecimal.ZERO);

                merchantStoreVoList.get(i).setOneYuanDenomination(0);
                merchantStoreVoList.get(i).setFiveYuanDenomination(0);
                merchantStoreVoList.get(i).setTenYuanDenomination(0);
                merchantStoreVoList.get(i).setTwentyYuanDenomination(0);
                merchantStoreVoList.get(i).setFiftyYuanDenomination(0);
                merchantStoreVoList.get(i).setOneHundredYuanDenomination(0);

                // 总营业额、线上支付总额、现金支付总额
                merchantStoreVoList.get(i).setTurnover(merchantStoreVoList.get(i).getTurnover().add(statsStoreVo.getTurnover()));
                merchantStoreVoList.get(i).setTurnoverOnLine(merchantStoreVoList.get(i).getTurnoverOnLine().add(statsStoreVo.getTurnoverOnLine()));
                merchantStoreVoList.get(i).setTurnoverOffline(merchantStoreVoList.get(i).getTurnoverOffline().add(statsStoreVo.getTurnoverOffline()));

                // 总投币数、线上投币总数、线下投币总数
                merchantStoreVoList.get(i).setInsertCoinOnLine(merchantStoreVoList.get(i).getInsertCoinOnLine() + statsStoreVo.getInsertCoinOnLine());
                merchantStoreVoList.get(i).setInsertCoinOffline(merchantStoreVoList.get(i).getInsertCoinOffline() + statsStoreVo.getInsertCoinOffline());
                merchantStoreVoList.get(i).setInsertCoinTotal(statsStoreVo.getInsertCoinOnLine() + statsStoreVo.getInsertCoinOffline());

                // 总兑币机出币
                merchantStoreVoList.get(i).setOutCoinTotal(merchantStoreVoList.get(i).getOutCoinTotal() + statsStoreVo.getOutCoinTotal());
                merchantStoreVoList.get(i).setFetchMemberOutCoinTotal(merchantStoreVoList.get(i).getFetchMemberOutCoinTotal() + statsStoreVo.getFetchMemberOutCoinTotal());

                // 总出礼数、总出礼成本、出礼率
                merchantStoreVoList.get(i).setGiftConsume(merchantStoreVoList.get(i).getGiftConsume() + statsStoreVo.getGiftConsume());
                merchantStoreVoList.get(i).setGiftCost(merchantStoreVoList.get(i).getGiftCost().add(statsStoreVo.getGiftCost()));

                Integer consumeCount = merchantStoreVoList.get(i).getConsumeRecordCount() + statsStoreVo.getConsumeRecordCount();
                Integer tuiLiIncrementTotal = merchantStoreVoList.get(i).getGiftConsume() + statsStoreVo.getGiftConsume();
                BigDecimal rate = BigDecimal.ZERO;
                if (consumeCount != 0) {
                    rate = BigDecimal.valueOf(tuiLiIncrementTotal).divide(new BigDecimal(String.valueOf(consumeCount)), 4, BigDecimal.ROUND_HALF_UP);
                } else if (consumeCount == 0 && tuiLiIncrementTotal.compareTo(0) == 1) {
                    // 投币次数为0，但有出礼
                    rate = BigDecimal.valueOf(1);
                }
                BigDecimal percentage = rate.multiply(new BigDecimal("100"));

                merchantStoreVoList.get(i).setGiftOutRate(percentage);

                merchantStoreVoList.get(i).setOneYuanDenomination(merchantStoreVoList.get(i).getOneYuanDenomination() + statsStoreVo.getOneYuanDenomination());
                merchantStoreVoList.get(i).setFiveYuanDenomination(merchantStoreVoList.get(i).getFiveYuanDenomination() + statsStoreVo.getFiveYuanDenomination());
                merchantStoreVoList.get(i).setTenYuanDenomination(merchantStoreVoList.get(i).getTenYuanDenomination() + statsStoreVo.getTenYuanDenomination());
                merchantStoreVoList.get(i).setTwentyYuanDenomination(merchantStoreVoList.get(i).getTwentyYuanDenomination() + statsStoreVo.getTwentyYuanDenomination());
                merchantStoreVoList.get(i).setFiftyYuanDenomination(merchantStoreVoList.get(i).getFiftyYuanDenomination() + statsStoreVo.getFiftyYuanDenomination());
                merchantStoreVoList.get(i).setOneHundredYuanDenomination(merchantStoreVoList.get(i).getOneHundredYuanDenomination() + statsStoreVo.getOneHundredYuanDenomination());
            }
            merchantStoreVoList.get(i).setMchStoreId(merchantStoreVoList.get(i).getId());
        }

        // 营收排序
        merchantStoreVoList = merchantStoreVoList.stream().sorted((item1, item2) -> {
            if (statsStoreDto.getTurnoverSort()) {
                return item1.getTurnover().compareTo(item2.getTurnover());
            } else {
                return item2.getTurnover().compareTo(item1.getTurnover());
            }
        }).collect(Collectors.toList());

        //总营业额
        BigDecimal turnover = BigDecimal.ZERO;
        //线上投币
        Integer insertCoinOnLine = 0;
        //线下投币
        Integer insertCoinOffline = 0;
        //礼品消耗数
        Integer giftConsume = 0;
        for (int i = 0; i < merchantStoreVoList.size(); i++) {
            turnover = turnover.add(merchantStoreVoList.get(i).getTurnover());
            insertCoinOnLine = insertCoinOnLine + merchantStoreVoList.get(i).getInsertCoinOnLine();
            insertCoinOffline = insertCoinOffline + merchantStoreVoList.get(i).getInsertCoinOffline();
            giftConsume = giftConsume + merchantStoreVoList.get(i).getGiftConsume();
        }

        StatsStoreVo statsStoreVo = new StatsStoreVo();
        statsStoreVo.setMerchantStoreVoList(merchantStoreVoList);
        statsStoreVo.setTurnover(turnover);
        statsStoreVo.setInsertCoinOnLine(insertCoinOnLine);
        statsStoreVo.setInsertCoinOffline(insertCoinOffline);
        statsStoreVo.setGiftConsume(giftConsume);


        return ServerResponse.createBySuccess(statsStoreVo);
    }

    /**
     * 统计兑币机每个面额收了多少次
     *
     * @param merchantStoreIdArray
     * @param startTime
     * @param endTime
     * @param sStore
     */
    @Override
    public void statsStoreDenomination(Integer[] merchantStoreIdArray, String startTime, String endTime, StatsStoreVo sStore) {
        String[] channelTypeArray = new String[]{
                ChannelTypeEnum.BILL_MACHINE.getCode(),
                ChannelTypeEnum.COIN_BOX.getCode()
        };
        Integer[] orderStatusArray = new Integer[]{
                OrderStatusEnum.SUCCESS.getCode(),
                OrderStatusEnum.PART_REFUND.getCode(),
                OrderStatusEnum.FULL_FERUND.getCode(),
                OrderStatusEnum.REFUNDING.getCode(),
        };


        OrderDto orderDenomination = new OrderDto();
        orderDenomination.setMerchantStoreIdArray(merchantStoreIdArray);
        orderDenomination.setStartTime(startTime);
        orderDenomination.setEndTime(endTime);
        orderDenomination.setMchType(MchTypeEnum.CASH_RECEIPTS.getCode());
        orderDenomination.setChannelTypeArray(channelTypeArray);
        orderDenomination.setOrderStatusArray(orderStatusArray);
        List<OrderVo> orderVoList = orderService.findDenominationCountByMerchantStoreId(orderDenomination);

        if (orderVoList.size() > 0) {
            StatsStoreDetail statsStoreDetail = new StatsStoreDetail();
            BeanUtils.copyProperties(sStore, statsStoreDetail);
            statsStoreDetailCommonService.statsStoreDetailDenomination(orderVoList, statsStoreDetail);
            BeanUtils.copyProperties(statsStoreDetail, sStore);
        }
    }

    @Override
    public StatsStoreVo findStatsStoreByMerchantStoreIdArray(StatsStoreDto statsStoreDto) {
        return statsStoreDao.findStatsStoreByMerchantStoreIdArray(statsStoreDto);
    }

    @Override
    public List<StatsStoreVo> findStoreStats(StatsStoreDto statsStoreDto) {
        statsStoreDto.setStatsType(StatsTypeEnum.statsUser.getCode());

        List<StatsStoreVo> statsStoreVoList = null;
        List<StatsStoreVo> todayStatsStoreVoList;
        List<StatsStoreVo> thisMonthStatsStoreVoList;

        if (statsStoreDto.getDayType() == 0) {
            statsStoreVoList = this.findTodayStatsStoreFromOrder(statsStoreDto);
        } else if (statsStoreDto.getDayType() == -1) {
            statsStoreDto.setType(1);
            statsStoreVoList = this.findFromStatsStore(statsStoreDto);

            if (statsStoreDto.getEndDateStr().equals(DateTimeUtils.getCurrentDateStr())) {
                todayStatsStoreVoList = this.findTodayStatsStoreFromOrder(statsStoreDto);
                this.twoStatsStoreVoAdd(statsStoreVoList, todayStatsStoreVoList);
            }
        } else {
            switch (statsStoreDto.getDayType()) {
                case 1:
                    //昨天
                    statsStoreDto.setStartDateStr(DateTimeUtils.getYesterday());
                    statsStoreDto.setEndDateStr(DateTimeUtils.getYesterday());
                    statsStoreDto.setType(1);
                    statsStoreVoList = this.findFromStatsStore(statsStoreDto);
                    break;
                case 2:
                    //本周
                    statsStoreDto.setStartDateStr(DateTimeUtils.getWeekFirstDay());
                    statsStoreDto.setEndDateStr(DateTimeUtils.getWeekLastDay());
                    statsStoreDto.setType(1);
                    statsStoreVoList = this.findFromStatsStore(statsStoreDto);

                    //当天
                    todayStatsStoreVoList = this.findTodayStatsStoreFromOrder(statsStoreDto);
                    this.twoStatsStoreVoAdd(statsStoreVoList, todayStatsStoreVoList);
                    break;
                case 3:
                    //本月
                    statsStoreVoList = this.getThisMonth(statsStoreDto);
                    break;
                case 4:
                    //上月
                    statsStoreDto.setStartDateStr(DateTimeUtils.getPreviousMonth());
                    statsStoreDto.setEndDateStr(DateTimeUtils.getPreviousMonth());
                    statsStoreDto.setType(2);
                    statsStoreVoList = this.findFromStatsStore(statsStoreDto);
                    break;
                case 5:
                    //半年
                    statsStoreDto.setStartDateStr(DateTimeUtils.getSomeMonthBefore(6));
                    statsStoreDto.setEndDateStr(DateTimeUtils.getMonthYM());
                    statsStoreDto.setType(2);
                    statsStoreVoList = this.findFromStatsStore(statsStoreDto);

                    thisMonthStatsStoreVoList = this.getThisMonth(statsStoreDto);
                    this.twoStatsStoreVoAdd(statsStoreVoList, thisMonthStatsStoreVoList);
                    break;
                case 6:
                    //半年
                    statsStoreDto.setStartDateStr(DateTimeUtils.getSomeMonthBefore(12));
                    statsStoreDto.setEndDateStr(DateTimeUtils.getMonthYM());
                    statsStoreDto.setType(2);
                    statsStoreVoList = this.findFromStatsStore(statsStoreDto);

                    thisMonthStatsStoreVoList = this.getThisMonth(statsStoreDto);
                    this.twoStatsStoreVoAdd(statsStoreVoList, thisMonthStatsStoreVoList);
                    break;
            }
        }

        statsStoreVoList.forEach(statsStoreVo -> {
            DeviceDto deviceDto = new DeviceDto();
            deviceDto.setUserInfo(statsStoreDto.getUserInfo());
            deviceDto.setMerchantStoreId(statsStoreVo.getMchStoreId());
            statsStoreVo.setTotalDevice(deviceService.findCountDeviceByMerchantStoreId(deviceDto));
        });

        return statsStoreVoList;
    }

    @Override
    public List<StatsStoreVo> findStoreStatsTwo(StatsStoreDto statsStoreDto) {
        statsStoreDto.setStatsType(StatsTypeEnum.statsUser.getCode());

        List<StatsStoreVo> statsStoreVoList = null;
        List<StatsStoreVo> todayStatsStoreVoList;
        List<StatsStoreVo> thisMonthStatsStoreVoList;

        if (statsStoreDto.getDayType() == 0) {
            statsStoreVoList = this.findTodayStatsStoreFromOrder(statsStoreDto);
        } else if (statsStoreDto.getDayType() == -1) {
            statsStoreDto.setType(1);
            statsStoreVoList = this.findFromStatsStore(statsStoreDto);
            if (statsStoreDto.getEndDateStr().equals(DateTimeUtils.getCurrentDateStr())) {
                todayStatsStoreVoList = this.findTodayStatsStoreFromOrder(statsStoreDto);
                this.twoStatsStoreVoAdd(statsStoreVoList, todayStatsStoreVoList);
            }
        } else {
            switch (statsStoreDto.getDayType()) {
                case 1:
                    //昨天
                    Date date = new Date();
                    String pattern = "HH";
                    Locale locale = Locale.getDefault();
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern, locale);
                    String time = simpleDateFormat.format(date);
                    Integer hour = Integer.parseInt(time);
                    if (hour >= 0 && hour <= 5) {
                        statsStoreDto.setHour(hour);
                        statsStoreVoList = this.findTodayStatsStoreFromOrder(statsStoreDto);
                    } else {
                        statsStoreDto.setStartDateStr(DateTimeUtils.getYesterday());
                        statsStoreDto.setEndDateStr(DateTimeUtils.getYesterday());
                        statsStoreDto.setType(1);
                        statsStoreVoList = this.findFromStatsStore(statsStoreDto);
                    }
                    break;
                case 2:
                    //本周
                    statsStoreDto.setStartDateStr(DateTimeUtils.getWeekFirstDay());
                    statsStoreDto.setEndDateStr(DateTimeUtils.getCurrTime());
                    statsStoreDto.setType(1);
                    statsStoreVoList = this.findFromStatsStore(statsStoreDto);

                    //当天
                    todayStatsStoreVoList = this.findTodayStatsStoreFromOrder(statsStoreDto);
                    this.twoStatsStoreVoAdd(statsStoreVoList, todayStatsStoreVoList);
                    break;
                case 3:
                    //本月
                    statsStoreVoList = this.getThisMonth(statsStoreDto);
                    break;
                case 4:
                    //今年
                    statsStoreDto.setStartDateStr(DateTimeUtils.getYearFirstDayTimeYM());
                    statsStoreDto.setEndDateStr(DateTimeUtils.getMonthYM());
                    statsStoreDto.setType(2);
                    statsStoreVoList = this.findFromStatsStore(statsStoreDto);
                    thisMonthStatsStoreVoList = this.getThisMonth(statsStoreDto);
                    this.twoStatsStoreVoAdd(statsStoreVoList, thisMonthStatsStoreVoList);
                    break;
                case 5:
                    //上月
                    statsStoreDto.setStartDateStr(DateTimeUtils.getPreviousMonthYM());
                    statsStoreDto.setEndDateStr(DateTimeUtils.getPreviousMonthYM());
                    statsStoreDto.setType(2);
                    statsStoreVoList = this.findFromStatsStore(statsStoreDto);
                    break;
            }
        }
        statsStoreVoList.forEach(statsStoreVo -> {
            DeviceDto deviceDto = new DeviceDto();
            deviceDto.setUserInfo(statsStoreDto.getUserInfo());
            deviceDto.setMerchantStoreId(statsStoreVo.getMchStoreId());
            statsStoreVo.setTotalDevice(deviceService.findCountDeviceByMerchantStoreId(deviceDto));
        });
        return statsStoreVoList;
    }

    private List<StatsStoreVo> getThisMonth(StatsStoreDto statsStoreDto) {
        statsStoreDto.setStartDateStr(DateTimeUtils.getMonthFirstDay());
        statsStoreDto.setEndDateStr(DateTimeUtils.getCurrTime());
        statsStoreDto.setType(1);
        List<StatsStoreVo> statsStoreVo = this.findFromStatsStore(statsStoreDto);

        //当天
        List<StatsStoreVo> todayStatsStoreVo = this.findTodayStatsStoreFromOrder(statsStoreDto);
        this.twoStatsStoreVoAdd(statsStoreVo, todayStatsStoreVo);

        return statsStoreVo;
    }

    private List<StatsStoreVo> findFromStatsStore(StatsStoreDto statsStoreDto) {
        List<StatsStoreVo> statsStoreVoList;

        List<MerchantStoreVo> merchantStoreVoList = merchantStoreService.findMerchantStoreIdByUserId(statsStoreDto.getUserInfo());

        statsStoreVoList = statsStoreDao.findStoreStats(statsStoreDto);
        if (statsStoreVoList.size() > 0) {
            List<StatsStoreVo> finalStatsStoreVoList = statsStoreVoList;
            merchantStoreVoList = merchantStoreVoList.stream().filter(add -> finalStatsStoreVoList.stream()
                    .noneMatch(all -> Objects.equals(add.getId(), all.getMchStoreId()))).collect(Collectors.toList());
            statsStoreVoList.forEach(statsStoreVo -> {
                BigDecimal activityTurnover = statsStoreVo.getSeckillMoney().add(statsStoreVo.getGroupBookingMoney()).add(statsStoreVo.getConsumptionOfRedEnvelopesMoney()).add(statsStoreVo.getMemberOfTheStoredValueMoney());
                statsStoreVo.setActivityTurnover(activityTurnover);
                Integer onLineOutCoinTotal = statsStoreVo.getOutCoinTotal() - statsStoreVo.getOffLinePayOutCoinTotal();
                statsStoreVo.setOnLineOutCoinTotal(onLineOutCoinTotal);
                //statsStoreVo.setTurnoverOnLine(statsStoreVo.getWxMoney().add(statsStoreVo.getAliMoney()).subtract(activityTurnover));
                //扫码支付 = 线上扫码 + 线下扫码
                statsStoreVo.setScanCodePayTotalTurnover(statsStoreVo.getTurnoverOnLine().add(statsStoreVo.getTurnoverOfflineCollectionCode()));
                //微信核销总出币 = 微信秒杀核销+微信拼团核销+微信凭证核销
                statsStoreVo.setWeiXinVerifyTotalCoin(
                        statsStoreVo.getWeiXinVoucherOutCoinTotal()
                                +statsStoreVo.getWeiXinSeckillOutCoinTotal()
                                +statsStoreVo.getWeiXinGroupBuyingOutCoinTotal());
                //售币总额turnoverGameCoin
                statsStoreVo.setTurnoverGameCoin(statsStoreVo.getTurnoverGameCoin()
                        .add(activityTurnover)
                        .add(statsStoreVo.getTurnoverMeiTuan())
                        .add(statsStoreVo.getTurnoverDouYin()));
                //币均价 = 售币总额 / 售币数
                if(statsStoreVo.getTurnoverGameCoin().compareTo(BigDecimal.ONE) > -1 &&
                        statsStoreVo.getQuantityOfCoinsSold().compareTo(1) > -1){
                    BigDecimal total = statsStoreVo.getTurnoverGameCoin().divide(new BigDecimal(statsStoreVo.getQuantityOfCoinsSold()), 4, BigDecimal.ROUND_HALF_UP);
                    statsStoreVo.setAverageCoinPrice(total.setScale(2, BigDecimal.ROUND_HALF_UP));
                }else{
                    statsStoreVo.setAverageCoinPrice(BigDecimal.ZERO);
                }


                if ((statsStoreDto.getDayType() <= 1 || statsStoreDto.getDayType() == 5) &&
                        !statsStoreDto.getEndDateStr().equals(DateTimeUtils.getCurrentDateStr())) {
                    this.outConStorePercent(statsStoreVo);
                    this.amountStorePercent(statsStoreVo);
                }
            });
        } else {
            statsStoreVoList = new ArrayList<>();
        }


        for (MerchantStoreVo merchantStoreVo : merchantStoreVoList) {
            StatsStoreVo statsStoreVo = new StatsStoreVo();
            statsStoreVo.setMchStoreId(merchantStoreVo.getId());
            statsStoreVo.setStoreName(merchantStoreVo.getStoreName());
            statsStoreVo.setTurnover(BigDecimal.valueOf(0));
            statsStoreVo.setSettlementMoney(BigDecimal.valueOf(0));
            statsStoreVo.setCashMoney(BigDecimal.valueOf(0));
            statsStoreVo.setTurnoverOnLine(BigDecimal.valueOf(0));
            statsStoreVo.setActivityTurnover(BigDecimal.valueOf(0));
            statsStoreVo.setOutCoinTotal(0);
            statsStoreVo.setOnLineOutCoinTotal(0);
            statsStoreVo.setOnLinePayOutCoinTotal(0);
            statsStoreVo.setOffLinePayOutCoinTotal(0);
            statsStoreVo.setInsertCoinTotal(0);
            statsStoreVo.setInsertCoinOnLine(0);
            statsStoreVo.setInsertCoinOffline(0);
            statsStoreVo.setGiftConsume(0);
            statsStoreVo.setGiftCost(BigDecimal.valueOf(0));
            statsStoreVo.setGiftOutRate(BigDecimal.valueOf(0));
            statsStoreVo.setIncomeCommodityTotal(0);
            statsStoreVo.setIncomeTotalIntegral(0);
            statsStoreVo.setExpendCommodityTotal(0);
            statsStoreVo.setExpendTotalIntegral(0);
            statsStoreVo.setTurnoverDouYin(BigDecimal.valueOf(0));
            statsStoreVo.setTurnoverMeiTuan(BigDecimal.valueOf(0));
            statsStoreVo.setFetchMemberOutCoinTotal(0);
            statsStoreVo.setDouYinOutCoinTotal(0);
            statsStoreVo.setMeiTuanOutCoinTotal(0);
            statsStoreVo.setArtificialOutCoinTotal(0);
            statsStoreVo.setWeiXinVerifyTotalCoin(0);
            statsStoreVo.setWeiXinSeckillOutCoinTotal(0);
            statsStoreVo.setWeiXinGroupBuyingOutCoinTotal(0);
            statsStoreVo.setWeiXinVoucherOutCoinTotal(0);
            statsStoreVo.setGameCoinRedPacketCoinTotal(0);
            statsStoreVo.setGroupBenefitCoinTotal(0);
            statsStoreVo.setDistributeBenefitCoinTotal(0);
            statsStoreVo.setQuantityOfCoinsSold(0);
            statsStoreVo.setAmountOfCoinsConsumed(0);
            statsStoreVo.setRemainingCoins(0);
            statsStoreVo.setAverageCoinPrice(BigDecimal.ZERO);
            statsStoreVo.setTurnoverGameCoin(BigDecimal.ZERO);
            statsStoreVo.setTurnoverOfflineCollectionCode(BigDecimal.ZERO);
            statsStoreVo.setScanCodePayTotalTurnover(BigDecimal.ZERO);
            statsStoreVo.setScanningFee(BigDecimal.ZERO);
            statsStoreVo.setTiktokCancellationFee(BigDecimal.ZERO);
            statsStoreVo.setMeiTuanCancellationFee(BigDecimal.ZERO);
            statsStoreVo.setIncomeTotalGameCoin(0);
            statsStoreVo.setIncomeCommodityGameCoin(0);

            statsStoreVo.setStoredValueRechargeBalance(BigDecimal.ZERO);
            statsStoreVo.setStoredValueComplimentaryBalance(BigDecimal.ZERO);
            statsStoreVo.setConsumeRechargeBalance(BigDecimal.ZERO);
            statsStoreVo.setConsumeComplimentaryBalance(BigDecimal.ZERO);

            this.initStorePercent(statsStoreVo);
            statsStoreVoList.add(statsStoreVo);
        }

        return statsStoreVoList;
    }

    /**
     * 当天
     */
    private List<StatsStoreVo> findTodayStatsStoreFromOrder(StatsStoreDto statsStoreDto) {
        if (ObjectUtils.isNotEmpty(statsStoreDto.getHour())) {
            //获取昨天的开始时间和结束时间 格式yyyy-MM-dd HH:mm:ss
            statsStoreDto.setStartTime(DateTimeUtils.parseLocalDate(DateTimeUtils.getYesterday()).format(DateTimeUtils.START_DATETIME_FORMATTER));
            statsStoreDto.setEndTime(DateTimeUtils.parseLocalDate(DateTimeUtils.getYesterday()).format(DateTimeUtils.END_DATETIME_FORMATTER));
        } else {
            statsStoreDto.setStartTime(DateTimeUtils.getTodayStartTime());
            statsStoreDto.setEndTime(DateTimeUtils.getTodayEndTime());
        }
        List<MerchantStoreVo> merchantStoreVoList = merchantStoreService.findMerchantStoreIdByUserId(statsStoreDto.getUserInfo());
        List<StatsStoreVo> statsStoreVoList = statsStoreDao.findOrderStatisticsGroupByStore(statsStoreDto);
        if (statsStoreVoList.size() > 0 && !StringUtils.isEmpty(statsStoreVoList.get(0).getMchStoreId())) {
            List<StatsStoreVo> finalStatsStoreVoList = statsStoreVoList;
            merchantStoreVoList = merchantStoreVoList.stream().filter(add -> finalStatsStoreVoList.stream()
                    .noneMatch(all -> Objects.equals(add.getId(), all.getMchStoreId()))).collect(Collectors.toList());
            statsStoreVoList.forEach(statsStoreVo -> {
                statsStoreVo.setInsertCoinTotal(0);
                statsStoreVo.setInsertCoinOffline(0);
                statsStoreVo.setInsertCoinOnLine(0);
                statsStoreDto.setConsumeRecordTypeIdArray(statsStoreDto.getInsertCoinConsumeRecordTypeIdArray());

                statsStoreDto.setMchStoreId(statsStoreVo.getMchStoreId());

                //当天的投币消费记录数，count值
                statsStoreDto.setConsumeRecordTypeId(ConsumeRecordTypeEnum.CONSUME.getCode());

                // 游戏币营业额，通用商品营业额，套票商品营业额
                StatsStoreVo statsStoreCommodity = statsStoreDao.findCommodityTypeByStoreIdTurnover(statsStoreDto);
                statsStoreVo.setTurnoverGameCoin(statsStoreCommodity.getTurnoverGameCoin()
                        .add(statsStoreVo.getActivityTurnover())
                        .add(statsStoreVo.getTurnoverMeiTuan())
                        .add(statsStoreVo.getTurnoverDouYin()));
                //币均价 = 售币总额 / 售币数
                if(statsStoreVo.getTurnoverGameCoin().compareTo(BigDecimal.ONE) > -1 &&
                        statsStoreVo.getQuantityOfCoinsSold().compareTo(1) > -1){
                    BigDecimal total = statsStoreVo.getTurnoverGameCoin().divide(new BigDecimal(statsStoreVo.getQuantityOfCoinsSold()), 4, BigDecimal.ROUND_HALF_UP);
                    statsStoreVo.setAverageCoinPrice(total.setScale(2, BigDecimal.ROUND_HALF_UP));
                }else{
                    statsStoreVo.setAverageCoinPrice(BigDecimal.ZERO);
                }


                //出币类型百分比,和金额百分比
                if(statsStoreDto.getDayType() == 0 || statsStoreDto.getDayType() == 1){
                    this.outConStorePercent(statsStoreVo);
                    this.amountStorePercent(statsStoreVo);
                }
            });
        } else {
            statsStoreVoList = new ArrayList<>();
        }

        for (MerchantStoreVo merchantStoreVo : merchantStoreVoList) {
            StatsStoreVo statsStoreVo = new StatsStoreVo();
            statsStoreVo.setMchStoreId(merchantStoreVo.getId());
            statsStoreVo.setStoreName(merchantStoreVo.getStoreName());
            statsStoreVo.setTurnover(BigDecimal.valueOf(0));
            statsStoreVo.setSettlementMoney(BigDecimal.valueOf(0));
            statsStoreVo.setCashMoney(BigDecimal.valueOf(0));
            statsStoreVo.setTurnoverOnLine(BigDecimal.valueOf(0));
            statsStoreVo.setActivityTurnover(BigDecimal.valueOf(0));
            statsStoreVo.setOutCoinTotal(0);
            statsStoreVo.setOnLineOutCoinTotal(0);
            statsStoreVo.setOnLinePayOutCoinTotal(0);
            statsStoreVo.setOffLinePayOutCoinTotal(0);
            statsStoreVo.setInsertCoinTotal(0);
            statsStoreVo.setInsertCoinOnLine(0);
            statsStoreVo.setInsertCoinOffline(0);
            statsStoreVo.setGiftConsume(0);
            statsStoreVo.setGiftCost(BigDecimal.valueOf(0));
            statsStoreVo.setGiftOutRate(BigDecimal.valueOf(0));
            statsStoreVo.setIncomeCommodityTotal(0);
            statsStoreVo.setIncomeTotalIntegral(0);
            statsStoreVo.setExpendCommodityTotal(0);
            statsStoreVo.setExpendTotalIntegral(0);
            statsStoreVo.setTurnoverDouYin(BigDecimal.valueOf(0));
            statsStoreVo.setTurnoverMeiTuan(BigDecimal.valueOf(0));
            statsStoreVo.setFetchMemberOutCoinTotal(0);
            statsStoreVo.setDouYinOutCoinTotal(0);
            statsStoreVo.setMeiTuanOutCoinTotal(0);
            statsStoreVo.setFetchMemberOutCoinTotal(0);
            statsStoreVo.setWeiXinVerifyTotalCoin(0);
            statsStoreVo.setWeiXinSeckillOutCoinTotal(0);
            statsStoreVo.setWeiXinGroupBuyingOutCoinTotal(0);
            statsStoreVo.setWeiXinVoucherOutCoinTotal(0);
            statsStoreVo.setArtificialOutCoinTotal(0);
            statsStoreVo.setGameCoinRedPacketCoinTotal(0);
            statsStoreVo.setGroupBenefitCoinTotal(0);
            statsStoreVo.setDistributeBenefitCoinTotal(0);
            statsStoreVo.setQuantityOfCoinsSold(0);
            statsStoreVo.setAmountOfCoinsConsumed(0);
            statsStoreVo.setRemainingCoins(0);
            statsStoreVo.setAverageCoinPrice(BigDecimal.ZERO);
            statsStoreVo.setTurnoverGameCoin(BigDecimal.ZERO);
            statsStoreVo.setTurnoverOfflineCollectionCode(BigDecimal.ZERO);
            statsStoreVo.setScanCodePayTotalTurnover(BigDecimal.ZERO);
            statsStoreVo.setScanningFee(BigDecimal.ZERO);
            statsStoreVo.setTiktokCancellationFee(BigDecimal.ZERO);
            statsStoreVo.setMeiTuanCancellationFee(BigDecimal.ZERO);
            statsStoreVo.setIncomeTotalGameCoin(0);
            statsStoreVo.setIncomeCommodityGameCoin(0);
            statsStoreVo.setStoredValueRechargeBalance(BigDecimal.ZERO);
            statsStoreVo.setStoredValueComplimentaryBalance(BigDecimal.ZERO);
            statsStoreVo.setConsumeRechargeBalance(BigDecimal.ZERO);
            statsStoreVo.setConsumeComplimentaryBalance(BigDecimal.ZERO);

            this.initStorePercent(statsStoreVo);
            statsStoreVoList.add(statsStoreVo);
        }
        return statsStoreVoList;
    }
    //初始化 百分比 0
    private void initStorePercent(StatsStoreVo statsStoreVo){
        BigDecimal money = new BigDecimal(0);
        statsStoreVo.setPercentCashMoney(money);
        statsStoreVo.setPercentActivityTurnover(money);
        statsStoreVo.setPercentTurnoverOnLine(money);
        statsStoreVo.setPercentTurnoverMeiTuan(money);
        statsStoreVo.setPercentTurnoverDouYin(money);
    }
    private void amountStorePercent(StatsStoreVo statsStoreVo){
        this.initStorePercent(statsStoreVo);
        if (statsStoreVo.getTurnover().compareTo(BigDecimal.ZERO) > 0) {
            ArrayList<BigDecimal> percentList = new ArrayList<>();
            //现金收款 除以 总营业额 保留两位小数 乘 100
            BigDecimal percentCashMoney = statsStoreVo.getCashMoney().divide(statsStoreVo.getTurnover(), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            statsStoreVo.setPercentCashMoney(percentCashMoney);
            percentList.add(percentCashMoney);
            // 活动总结算额 除以 总营业额 保留两位小数 乘 100
            BigDecimal activityTurnover1 = statsStoreVo.getActivityTurnover().divide(statsStoreVo.getTurnover(), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            statsStoreVo.setPercentActivityTurnover(activityTurnover1);
            percentList.add(activityTurnover1);

            // 线上营业额  除以 总营业额 保留两位小数 乘 100
            BigDecimal percentTurnoverOnLine = statsStoreVo.getScanCodePayTotalTurnover().divide(statsStoreVo.getTurnover(), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            statsStoreVo.setPercentTurnoverOnLine(percentTurnoverOnLine);
            percentList.add(percentTurnoverOnLine);

            //抖音收款
            BigDecimal percentTurnoverDouYin = statsStoreVo.getTurnoverDouYin().divide(statsStoreVo.getTurnover(), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            statsStoreVo.setPercentTurnoverDouYin(percentTurnoverDouYin);
            percentList.add(percentTurnoverDouYin);

            //美团收款
            BigDecimal percentTurnoverMeiTuan = statsStoreVo.getTurnoverMeiTuan().divide(statsStoreVo.getTurnover(), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            statsStoreVo.setPercentTurnoverMeiTuan(percentTurnoverMeiTuan);
            percentList.add(percentTurnoverMeiTuan);
            BigDecimal maxPercent = Collections.max(percentList);
            BigDecimal bfb = new BigDecimal(100);
            //0是现金，1是活动...
            Integer index = -1;
            boolean flog = true;
            if(maxPercent.compareTo(BigDecimal.ZERO) == 1){
                for(int i = 0; i < percentList.size(); i++){
                    if(percentList.get(i).compareTo(maxPercent) == 0 && flog){
                        //记录最大百分比坐标
                        index = i;
                        flog = false;
                        continue;
                    }
                    bfb = bfb.subtract(percentList.get(i));
                }
                switch (index){
                    case 0:
                        statsStoreVo.setPercentCashMoney(bfb);
                        break;
                    case 1:
                        statsStoreVo.setPercentActivityTurnover(bfb);
                        break;
                    case 2:
                        statsStoreVo.setPercentTurnoverOnLine(bfb);
                        break;
                    case 3:
                        statsStoreVo.setPercentTurnoverDouYin(bfb);
                        break;
                    case 4:
                        statsStoreVo.setPercentTurnoverMeiTuan(bfb);
                        break;
                }
            }
        }
    }
    private void outConStorePercent(StatsStoreVo statsStoreVo) {
        //初始化
        BigDecimal rate = new BigDecimal(0);
        statsStoreVo.setPercentOffLinePayOutCoin(rate);
        statsStoreVo.setPercentFetchMemberOutCoin(rate);
        statsStoreVo.setPercentOnLinePayOutCoinTotal(rate);
        statsStoreVo.setPercentOnLinePayOutCoinTotal(rate);
        statsStoreVo.setPercentArtificialOutCoin(rate);
        statsStoreVo.setPercentMeiTuanOutCoin(rate);
        statsStoreVo.setPercentDouYinOutCoin(rate);
        statsStoreVo.setPercentWeiXinVerifyOutCoin(rate);
        statsStoreVo.setPercentInsertCoinOffline(rate);
        statsStoreVo.setPercentInsertCoinOnLine(rate);
        statsStoreVo.setPercentDistributeBenefitCoin(rate);
        statsStoreVo.setPercentCoinRedPacketCoin(rate);
        //购币情况
        if(statsStoreVo.getQuantityOfCoinsSold() > 0){
            //BigDecimal total = new BigDecimal(statsStoreVo.getOutCoinTotal());
            BigDecimal total = new BigDecimal(statsStoreVo.getQuantityOfCoinsSold());
            // 现金出币 除以 总出币 保留两位小数 乘 100
            BigDecimal offLinePayOutCoinTotal = new BigDecimal(statsStoreVo.getOffLinePayOutCoinTotal());
            BigDecimal offLinePayOutCoinTotalRate = offLinePayOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentOffLinePayOutCoin(offLinePayOutCoinTotalRate.multiply(new BigDecimal("100")));

            //线上出币
            BigDecimal linePayOutCoinTotal = new BigDecimal(statsStoreVo.getOnLinePayOutCoinTotal());
            BigDecimal linePayOutCoinTotalRate = linePayOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentOnLinePayOutCoinTotal(linePayOutCoinTotalRate.multiply(new BigDecimal("100")));

            //会员取币
            BigDecimal fetchMemberOutCoinTotal = new BigDecimal(statsStoreVo.getFetchMemberOutCoinTotal());
            BigDecimal fetchMemberOutCoinTotalRate = fetchMemberOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentFetchMemberOutCoin(fetchMemberOutCoinTotalRate.multiply(new BigDecimal("100")));

            //抖音核销出币
            BigDecimal douYinOutCoinTotal = new BigDecimal(statsStoreVo.getDouYinOutCoinTotal());
            BigDecimal douYinOutCoinTotalRate = douYinOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentDouYinOutCoin(douYinOutCoinTotalRate.multiply(new BigDecimal("100")));

            //美团核销出币
            BigDecimal meiTuanOutCoinTotal = new BigDecimal(statsStoreVo.getMeiTuanOutCoinTotal());
            BigDecimal meiTuanOutCoinTotalRate = meiTuanOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentMeiTuanOutCoin(meiTuanOutCoinTotalRate.multiply(new BigDecimal("100")));

            //微信核销出币
            BigDecimal weiXinVerifyOutCoinTotal = new BigDecimal(statsStoreVo.getWeiXinVerifyTotalCoin());
            BigDecimal weiXinVerifyOutCoinTotalRate = weiXinVerifyOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentWeiXinVerifyOutCoin(weiXinVerifyOutCoinTotalRate.multiply(new BigDecimal("100")));

            //人工出币
            BigDecimal artificialOutCoinTotal = new BigDecimal(statsStoreVo.getArtificialOutCoinTotal());
            BigDecimal artificialOutCoinTotalRate = artificialOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentArtificialOutCoin(artificialOutCoinTotalRate.multiply(new BigDecimal("100")));


            //游戏币红包币
            BigDecimal gameCoinRedPacketCoinTotal = new BigDecimal(statsStoreVo.getGameCoinRedPacketCoinTotal());
            BigDecimal gameCoinRedPacketCoinTotalRate = gameCoinRedPacketCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentCoinRedPacketCoin(gameCoinRedPacketCoinTotalRate.multiply(new BigDecimal("100")));
            //加群福利币
            BigDecimal groupBenefitCoinTotal = new BigDecimal(statsStoreVo.getGroupBenefitCoinTotal());
            BigDecimal groupBenefitCoinTotalRate = groupBenefitCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentGroupBenefitCoin(groupBenefitCoinTotalRate.multiply(new BigDecimal("100")));

            //派发福利币
            BigDecimal distributeBenefitCoinTotal = new BigDecimal(statsStoreVo.getDistributeBenefitCoinTotal());
            BigDecimal distributeBenefitCoinTotalRate = distributeBenefitCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentDistributeBenefitCoin(distributeBenefitCoinTotalRate.multiply(new BigDecimal("100")));

        }

        //投币情况
        if(statsStoreVo.getInsertCoinTotal() > 0){
            BigDecimal total = new BigDecimal(statsStoreVo.getInsertCoinTotal());
            //线上投币
            BigDecimal insertCoinOnLine = new BigDecimal(statsStoreVo.getInsertCoinOnLine());
            BigDecimal insertCoinOnLineRate = insertCoinOnLine.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentInsertCoinOnLine(insertCoinOnLineRate.multiply(new BigDecimal("100")));

            //线下投币
            BigDecimal insertCoinOffline = new BigDecimal(statsStoreVo.getInsertCoinOffline());
            BigDecimal insertCoinOfflineRate = insertCoinOffline.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentInsertCoinOffline(insertCoinOfflineRate.multiply(new BigDecimal("100")));
        }

    }

    private void twoStatsStoreVoAdd(List<StatsStoreVo> statsStoreVoList, List<StatsStoreVo> statsStoreVoList2) {

        statsStoreVoList.forEach(statsStoreVo -> statsStoreVoList2.forEach(statsStoreVo2 -> {
            if (statsStoreVo.getMchStoreId().equals(statsStoreVo2.getMchStoreId())) {
                //会员 出币
                statsStoreVo.setFetchMemberOutCoinTotal(statsStoreVo2.getFetchMemberOutCoinTotal() + statsStoreVo.getFetchMemberOutCoinTotal());
                //抖音核销 出币
                statsStoreVo.setDouYinOutCoinTotal(statsStoreVo2.getDouYinOutCoinTotal() + statsStoreVo.getDouYinOutCoinTotal());
                //美团核销 出币
                statsStoreVo.setMeiTuanOutCoinTotal(statsStoreVo2.getMeiTuanOutCoinTotal() + statsStoreVo.getMeiTuanOutCoinTotal());
                //人工出币
                statsStoreVo.setArtificialOutCoinTotal(statsStoreVo2.getArtificialOutCoinTotal() + statsStoreVo.getArtificialOutCoinTotal());
                //微信秒杀核销
                statsStoreVo.setWeiXinSeckillOutCoinTotal(statsStoreVo2.getWeiXinSeckillOutCoinTotal() + statsStoreVo.getWeiXinSeckillOutCoinTotal());
                //微信拼团核销
                statsStoreVo.setWeiXinGroupBuyingOutCoinTotal(statsStoreVo2.getWeiXinGroupBuyingOutCoinTotal() + statsStoreVo.getWeiXinGroupBuyingOutCoinTotal());
                //微信凭证核销
                statsStoreVo.setWeiXinVoucherOutCoinTotal(statsStoreVo2.getWeiXinVoucherOutCoinTotal()+statsStoreVo.getWeiXinVoucherOutCoinTotal());
                //在线出币
                statsStoreVo.setOnLinePayOutCoinTotal(statsStoreVo2.getOnLinePayOutCoinTotal()+statsStoreVo.getOnLinePayOutCoinTotal());
                //微信核销
                statsStoreVo.setWeiXinVerifyTotalCoin(statsStoreVo2.getWeiXinVerifyTotalCoin()+statsStoreVo.getWeiXinVerifyTotalCoin());
                //游戏红包币
                statsStoreVo.setGameCoinRedPacketCoinTotal(statsStoreVo2.getGameCoinRedPacketCoinTotal()+statsStoreVo.getGameCoinRedPacketCoinTotal());
                //加群福利币
                statsStoreVo.setGroupBenefitCoinTotal(statsStoreVo2.getGroupBenefitCoinTotal()+statsStoreVo.getGroupBenefitCoinTotal());
                //派发福利币
                statsStoreVo.setDistributeBenefitCoinTotal(statsStoreVo2.getDistributeBenefitCoinTotal()+statsStoreVo.getDistributeBenefitCoinTotal());
                //售币数（游戏币销售数量）
                statsStoreVo.setQuantityOfCoinsSold(statsStoreVo2.getQuantityOfCoinsSold()+statsStoreVo.getQuantityOfCoinsSold());
                //出币数（游戏币消耗数量）
                statsStoreVo.setAmountOfCoinsConsumed(statsStoreVo2.getAmountOfCoinsConsumed()+statsStoreVo.getAmountOfCoinsConsumed());
                //余币数 = 售币数-消耗数
                statsStoreVo.setRemainingCoins(statsStoreVo.getQuantityOfCoinsSold()-statsStoreVo.getAmountOfCoinsConsumed());
                //游戏币营业额
                statsStoreVo.setTurnoverGameCoin(statsStoreVo2.getTurnoverGameCoin().add(statsStoreVo.getTurnoverGameCoin()));
                //币均价 = 售币总额 / 售币数
                if(statsStoreVo.getTurnoverGameCoin().compareTo(BigDecimal.ONE) > -1 &&
                        statsStoreVo.getQuantityOfCoinsSold().compareTo(1) > -1){
                    BigDecimal total = statsStoreVo.getTurnoverGameCoin().divide(new BigDecimal(statsStoreVo.getQuantityOfCoinsSold()), 4, BigDecimal.ROUND_HALF_UP);
                    statsStoreVo.setAverageCoinPrice(total.setScale(2, BigDecimal.ROUND_HALF_UP));
                }else{
                    statsStoreVo.setAverageCoinPrice(BigDecimal.ZERO);
                }
                statsStoreVo.setTurnover(statsStoreVo2.getTurnover().add(statsStoreVo.getTurnover()));
                statsStoreVo.setSettlementMoney(statsStoreVo2.getSettlementMoney().add(statsStoreVo.getSettlementMoney()));
                statsStoreVo.setCashMoney(statsStoreVo2.getCashMoney().add(statsStoreVo.getCashMoney()));
                statsStoreVo.setTurnoverOnLine(statsStoreVo2.getTurnoverOnLine().add(statsStoreVo.getTurnoverOnLine()));
                statsStoreVo.setActivityTurnover(statsStoreVo2.getActivityTurnover().add(statsStoreVo.getActivityTurnover()));
                statsStoreVo.setOutCoinTotal(statsStoreVo2.getOutCoinTotal() + statsStoreVo.getOutCoinTotal());
                statsStoreVo.setOnLineOutCoinTotal(statsStoreVo2.getOnLineOutCoinTotal() + statsStoreVo.getOnLineOutCoinTotal());
                statsStoreVo.setOffLinePayOutCoinTotal(statsStoreVo2.getOffLinePayOutCoinTotal() + statsStoreVo.getOffLinePayOutCoinTotal());
                statsStoreVo.setInsertCoinTotal(statsStoreVo2.getInsertCoinTotal() + statsStoreVo.getInsertCoinTotal());
                statsStoreVo.setInsertCoinOnLine(statsStoreVo2.getInsertCoinOnLine() + statsStoreVo.getInsertCoinOnLine());
                statsStoreVo.setInsertCoinOffline(statsStoreVo2.getInsertCoinOffline() + statsStoreVo.getInsertCoinOffline());
                statsStoreVo.setGiftConsume(statsStoreVo2.getGiftConsume() + statsStoreVo.getGiftConsume());
                statsStoreVo.setGiftCost(statsStoreVo2.getGiftCost().add(statsStoreVo.getGiftCost()));
                statsStoreVo.setGiftOutRate(statsStoreVo2.getGiftOutRate().add(statsStoreVo.getGiftOutRate()));
                statsStoreVo.setIncomeCommodityTotal(statsStoreVo2.getIncomeCommodityTotal() + statsStoreVo.getIncomeCommodityTotal());
                statsStoreVo.setIncomeTotalIntegral(statsStoreVo2.getIncomeTotalIntegral() + statsStoreVo.getIncomeTotalIntegral());
                statsStoreVo.setExpendCommodityTotal(statsStoreVo2.getExpendCommodityTotal() + statsStoreVo.getExpendCommodityTotal());
                statsStoreVo.setExpendTotalIntegral(statsStoreVo2.getExpendTotalIntegral() + statsStoreVo.getExpendTotalIntegral());
                statsStoreVo.setTurnoverDouYin(statsStoreVo2.getTurnoverDouYin().add(statsStoreVo.getTurnoverDouYin()));
                statsStoreVo.setTurnoverMeiTuan(statsStoreVo2.getTurnoverMeiTuan().add(statsStoreVo.getTurnoverMeiTuan()));
                statsStoreVo.setScanCodePayTotalTurnover(statsStoreVo2.getScanCodePayTotalTurnover().add(statsStoreVo.getScanCodePayTotalTurnover()));
                statsStoreVo.setScanningFee(statsStoreVo2.getScanningFee().add(statsStoreVo.getScanningFee()));
                statsStoreVo.setTiktokCancellationFee(statsStoreVo2.getTiktokCancellationFee().add(statsStoreVo.getTiktokCancellationFee()));
                statsStoreVo.setMeiTuanCancellationFee(statsStoreVo2.getMeiTuanCancellationFee().add(statsStoreVo.getMeiTuanCancellationFee()));
                statsStoreVo.setIncomeTotalGameCoin(statsStoreVo2.getIncomeTotalGameCoin() +statsStoreVo.getIncomeTotalGameCoin() );
                statsStoreVo.setIncomeCommodityGameCoin(statsStoreVo2.getIncomeCommodityGameCoin() + statsStoreVo.getIncomeCommodityGameCoin());

                statsStoreVo.setStoredValueRechargeBalance(statsStoreVo2.getStoredValueRechargeBalance().add(statsStoreVo.getStoredValueRechargeBalance()));
                statsStoreVo.setStoredValueComplimentaryBalance(statsStoreVo2.getStoredValueComplimentaryBalance().add(statsStoreVo.getStoredValueRechargeBalance()));
                statsStoreVo.setConsumeRechargeBalance(statsStoreVo2.getConsumeRechargeBalance().add(statsStoreVo.getStoredValueRechargeBalance()));
                statsStoreVo.setConsumeComplimentaryBalance(statsStoreVo2.getConsumeComplimentaryBalance().add(statsStoreVo.getStoredValueRechargeBalance()));

                this.outConStorePercent(statsStoreVo);
                this.amountStorePercent(statsStoreVo);
            }
        }));
    }

    /**
     * 根据开始结束时间, 场地ID, 查询日或月的统计数据
     */
    @Override
    public List<StatsStoreVo> findStoreStatsStateList(StatsStoreDto statsStoreDto) {
        // 限制日范围最大不超过60天，月范围最大不超过24个月
        DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        if(StatisticsTypeEnum.MONTH.getCode().equals(statsStoreDto.getType())){
            LocalDate startLocalDate = LocalDate.parse(statsStoreDto.getStartDateStr()+"-01", DATE_FORMATTER);
            LocalDate endLocalDate = LocalDate.parse(statsStoreDto.getEndDateStr()+"-01", DATE_FORMATTER);
            // 本月没算上去,所以需要 +1
            long day = DateTimeUtils.periodMonths(startLocalDate,endLocalDate) + 1;
            if(day > 24){
                throw new RuntimeException("最多不能超过24个月");
            }
        }else if(StatisticsTypeEnum.DAY.getCode().equals(statsStoreDto.getType())){
            LocalDate startLocalDate = LocalDate.parse(statsStoreDto.getStartDateStr(), DATE_FORMATTER);
            LocalDate endLocalDate = LocalDate.parse(statsStoreDto.getEndDateStr(), DATE_FORMATTER);
            // 本日没算上去,所以需要 +1
            long day = DateTimeUtils.periodDays(startLocalDate,endLocalDate) + 1;
            if(day > 60){
                throw new RuntimeException("最多不能超过60天");
            }
        }

        statsStoreDto.setStatsType(StatsTypeEnum.statsUser.getCode());
        List<StatsStoreVo> list = statsStoreDao.findStoreStatsStateList(statsStoreDto);
        return list;
    }
    /**
     * 查询全部场地统计V3
     * */
    @Override
    public StatsStoreVo findAllStatsStoreList(StatsStoreDto statsStoreDto) {
        StatsStoreVo statsStoreVo = new StatsStoreVo();
        statsStoreDto.setStatsType(StatsTypeEnum.statsUser.getCode());
        List<StatsStoreVo> statsStoreVoList = null;
        List<StatsStoreVo> todayStatsStoreVoList;
        List<StatsStoreVo> thisMonthStatsStoreVoList;
        if (statsStoreDto.getDayType().compareTo(StatsDayTypeEnum.TODAY.getCode()) == 0) {
            //统计总的user
            statsStoreVo = this.findTodayStatsUserFromOrder(statsStoreDto);
            //场地统计
            statsStoreVoList = this.findTodayStatsStoreFromOrderV2(statsStoreDto);
        } else if (statsStoreDto.getDayType().compareTo(StatsDayTypeEnum.CUSTOM_TIME.getCode()) == 0) {
            statsStoreDto.setType(StatisticsTypeEnum.DAY.getCode());
            statsStoreVo = this.findFromStatsUser(statsStoreDto);
            statsStoreVoList = this.findFromStatsStoreV2(statsStoreDto);
            //包含了当天
            if (statsStoreDto.getEndDateStr().equals(DateTimeUtils.getCurrentDateStr())) {
                //场地
                todayStatsStoreVoList = this.findTodayStatsStoreFromOrderV2(statsStoreDto);
                this.statsStoreVoListAdd(statsStoreVoList, todayStatsStoreVoList);

                StatsStoreVo todayStatsStoreVo = this.findTodayStatsUserFromOrder(statsStoreDto);
                this.statsUserVoAdd(statsStoreVo,todayStatsStoreVo);
            }
        }else if (statsStoreDto.getDayType().compareTo(StatsDayTypeEnum.YESTERDAY.getCode()) == 0){
             //昨天数据统计
            // 获取当前时间
            LocalDateTime now = LocalDateTime.now();
            // 获取当前小时（24小时制）凌晨0点到六点前，调用今日统计的数据
            int hour = now.getHour();
            if (hour >= 0 && hour <= 5) {
                statsStoreDto.setHour(hour);
                statsStoreVo = this.findTodayStatsUserFromOrder(statsStoreDto);
                statsStoreVoList = this.findTodayStatsStoreFromOrderV2(statsStoreDto);
            } else {
                statsStoreDto.setStartDateStr(DateTimeUtils.getYesterday());
                statsStoreDto.setEndDateStr(DateTimeUtils.getYesterday());
                statsStoreDto.setType(StatisticsTypeEnum.DAY.getCode());
                statsStoreVo = this.findFromStatsUser(statsStoreDto);
                statsStoreVoList = this.findFromStatsStoreV2(statsStoreDto);
            }
        }else if (statsStoreDto.getDayType().compareTo(StatsDayTypeEnum.THIS_WEEK.getCode()) == 0){
            //本周
        }else if (statsStoreDto.getDayType().compareTo(StatsDayTypeEnum.THIS_MONTH.getCode()) == 0){
            //本月
            statsStoreDto.setStartDateStr(DateTimeUtils.getMonthFirstDay());
            statsStoreDto.setEndDateStr(DateTimeUtils.getCurrTime());
            statsStoreVo = this.getThisMonthUser(statsStoreDto);
            statsStoreVoList = this.getThisMonthStore(statsStoreDto);
        }else if (statsStoreDto.getDayType().compareTo(StatsDayTypeEnum.LAST_MONTH.getCode()) == 0){
            //上月
            statsStoreDto.setStartDateStr(DateTimeUtils.getPreviousMonthYM());
            statsStoreDto.setEndDateStr(DateTimeUtils.getPreviousMonthYM());
            statsStoreDto.setType(StatisticsTypeEnum.MONTH.getCode());
            statsStoreVo = this.findFromStatsUser(statsStoreDto);
            statsStoreVoList = this.findFromStatsStoreV2(statsStoreDto);
        }else if (statsStoreDto.getDayType().compareTo(StatsDayTypeEnum.THIS_YEAR.getCode()) == 0){
            //今年
            statsStoreDto.setStartDateStr(DateTimeUtils.getYearFirstDayTimeYM());
            statsStoreDto.setEndDateStr(DateTimeUtils.getMonthYM());
            statsStoreDto.setType(StatisticsTypeEnum.MONTH.getCode());
            statsStoreVoList = this.findFromStatsStoreV2(statsStoreDto);
            statsStoreVo = this.findFromStatsUser(statsStoreDto);
            //今年包含本月，本月包含了当天
            statsStoreDto.setStartDateStr(DateTimeUtils.getMonthFirstDay());
            statsStoreDto.setEndDateStr(DateTimeUtils.getCurrTime());
            thisMonthStatsStoreVoList = this.getThisMonthStore(statsStoreDto);
            this.statsStoreVoListAdd(statsStoreVoList, thisMonthStatsStoreVoList);
            StatsStoreVo storeVo = this.getThisMonthUser(statsStoreDto);
            this.statsUserVoAdd(statsStoreVo, storeVo);
        } else{
            throw new RuntimeException("缺少日期分支");
        }
        //全部设备
        DeviceDto deviceDto = new DeviceDto();
        deviceDto.setUserInfo(statsStoreDto.getUserInfo());
        Integer totalDevice = deviceService.findDeviceCountByUserId(deviceDto);
        statsStoreVo.setTotalDevice(totalDevice);
        statsStoreVo.setStatsStoreVoList(statsStoreVoList.stream()
                .sorted((o1, o2) -> o2.getTurnover().compareTo(o1.getTurnover())) // 降序排序
                .collect(Collectors.toList()));
        return statsStoreVo;
    }


    @Override
    public StatsStoreVo findStatsStoreByStoreId(StatsStoreDto statsStoreDto) {
        return statsStoreDao.findStatsStoreByStoreId(statsStoreDto);
    }

    /**
     * 统计场地本月数据（包含当天）
     * */
    private List<StatsStoreVo> getThisMonthStore(StatsStoreDto statsStoreDto) {
        statsStoreDto.setType(StatisticsTypeEnum.DAY.getCode());
        List<StatsStoreVo> statsStoreVo = this.findFromStatsStoreV2(statsStoreDto);

        //当天
        List<StatsStoreVo> todayStatsStoreVo = this.findTodayStatsStoreFromOrderV2(statsStoreDto);
        this.statsStoreVoListAdd(statsStoreVo, todayStatsStoreVo);
        return statsStoreVo;
    }

    /**
     * 场地数据合并
     *
     * */
    private void statsStoreVoListAdd(List<StatsStoreVo> statsStoreVoList, List<StatsStoreVo> todayStatsStoreList) {
        // 使用Map集合可以避免双重循环提高效率
        Map<Integer, StatsStoreVo> statsDeviceMap = todayStatsStoreList.stream().collect(Collectors.toMap(StatsStoreVo::getMchStoreId, v -> v));

        for (StatsStoreVo statsStoreVo : statsStoreVoList){
            StatsStoreVo statsStoreVo2 = statsDeviceMap.get(statsStoreVo.getMchStoreId());
            if(ObjectUtils.isEmpty(statsStoreVo2)){
                continue;
            }
            //门店套餐
            List<StatsUserVo> storePackageData = this.publicPackageData(statsStoreVo2.getStatistStorePackageList(), statsStoreVo.getStatistStorePackageList());
            statsStoreVo.setStatistStorePackageList(storePackageData);

            //抖音套餐
            List<StatsUserVo> douYinPackageData = this.publicPackageData(statsStoreVo2.getStatistDouYinPackageList(), statsStoreVo.getStatistDouYinPackageList());
            statsStoreVo.setStatistDouYinPackageList(douYinPackageData);

            //美团套餐
            List<StatsUserVo> meiTuanPackageData = this.publicPackageData(statsStoreVo2.getStatistMeiTuanPackageList(), statsStoreVo.getStatistMeiTuanPackageList());
            statsStoreVo.setStatistDouYinPackageList(meiTuanPackageData);

            // 核实套票
            List<StatsUserVo> mergedData = this.mergeTicketUsageData(statsStoreVo2.getStatistTicketUsageRecordList(), statsStoreVo.getStatistTicketUsageRecordList());
            statsStoreVo.setStatistTicketUsageRecordList(mergedData);

            //会员 出币
            statsStoreVo.setFetchMemberOutCoinTotal(statsStoreVo2.getFetchMemberOutCoinTotal() + statsStoreVo.getFetchMemberOutCoinTotal());
            //抖音核销 出币
            statsStoreVo.setDouYinOutCoinTotal(statsStoreVo2.getDouYinOutCoinTotal() + statsStoreVo.getDouYinOutCoinTotal());
            //美团核销 出币
            statsStoreVo.setMeiTuanOutCoinTotal(statsStoreVo2.getMeiTuanOutCoinTotal() + statsStoreVo.getMeiTuanOutCoinTotal());
            //人工出币
            statsStoreVo.setArtificialOutCoinTotal(statsStoreVo2.getArtificialOutCoinTotal() + statsStoreVo.getArtificialOutCoinTotal());
            //微信秒杀核销
            statsStoreVo.setWeiXinSeckillOutCoinTotal(statsStoreVo2.getWeiXinSeckillOutCoinTotal() + statsStoreVo.getWeiXinSeckillOutCoinTotal());
            //微信拼团核销
            statsStoreVo.setWeiXinGroupBuyingOutCoinTotal(statsStoreVo2.getWeiXinGroupBuyingOutCoinTotal() + statsStoreVo.getWeiXinGroupBuyingOutCoinTotal());
            //微信凭证核销
            statsStoreVo.setWeiXinVoucherOutCoinTotal(statsStoreVo2.getWeiXinVoucherOutCoinTotal()+statsStoreVo.getWeiXinVoucherOutCoinTotal());
            //微信核销总出币 = 微信秒杀核销+微信拼团核销+微信凭证核销
            statsStoreVo.setWeiXinVerifyTotalCoin(statsStoreVo2.getWeiXinVerifyTotalCoin()+statsStoreVo.getWeiXinVerifyTotalCoin());
            //在线出币
            statsStoreVo.setOnLinePayOutCoinTotal(statsStoreVo2.getOnLinePayOutCoinTotal()+statsStoreVo.getOnLinePayOutCoinTotal());
            //游戏红包币
            statsStoreVo.setGameCoinRedPacketCoinTotal(statsStoreVo2.getGameCoinRedPacketCoinTotal()+statsStoreVo.getGameCoinRedPacketCoinTotal());
            //加群福利币
            statsStoreVo.setGroupBenefitCoinTotal(statsStoreVo2.getGroupBenefitCoinTotal()+statsStoreVo.getGroupBenefitCoinTotal());
            //派发福利币
            statsStoreVo.setDistributeBenefitCoinTotal(statsStoreVo2.getDistributeBenefitCoinTotal()+statsStoreVo.getDistributeBenefitCoinTotal());
            //售币数（游戏币销售数量）
            statsStoreVo.setQuantityOfCoinsSold(statsStoreVo2.getQuantityOfCoinsSold()+statsStoreVo.getQuantityOfCoinsSold());
            //出币数（游戏币消耗数量）
            statsStoreVo.setAmountOfCoinsConsumed(statsStoreVo2.getAmountOfCoinsConsumed()+statsStoreVo.getAmountOfCoinsConsumed());
            //余币数 = 售币数-消耗数
            statsStoreVo.setRemainingCoins(statsStoreVo.getQuantityOfCoinsSold()-statsStoreVo.getAmountOfCoinsConsumed());
            //游戏币营业额
            statsStoreVo.setTurnoverGameCoin(statsStoreVo2.getTurnoverGameCoin().add(statsStoreVo.getTurnoverGameCoin()));
            //币均价 = 售币总额 / 售币数
            if(statsStoreVo.getTurnoverGameCoin().compareTo(BigDecimal.ONE) > -1 &&
                    statsStoreVo.getQuantityOfCoinsSold().compareTo(1) > -1){
                BigDecimal total = statsStoreVo.getTurnoverGameCoin().divide(new BigDecimal(statsStoreVo.getQuantityOfCoinsSold()), 4, BigDecimal.ROUND_HALF_UP);
                statsStoreVo.setAverageCoinPrice(total.setScale(2, BigDecimal.ROUND_HALF_UP));
            }else{
                statsStoreVo.setAverageCoinPrice(BigDecimal.ZERO);
            }
            statsStoreVo.setTurnover(statsStoreVo2.getTurnover().add(statsStoreVo.getTurnover()));
            statsStoreVo.setSettlementMoney(statsStoreVo2.getSettlementMoney().add(statsStoreVo.getSettlementMoney()));
            statsStoreVo.setCashMoney(statsStoreVo2.getCashMoney().add(statsStoreVo.getCashMoney()));
            statsStoreVo.setTurnoverOnLine(statsStoreVo2.getTurnoverOnLine().add(statsStoreVo.getTurnoverOnLine()));
            statsStoreVo.setActivityTurnover(statsStoreVo2.getActivityTurnover().add(statsStoreVo.getActivityTurnover()));
            statsStoreVo.setOutCoinTotal(statsStoreVo2.getOutCoinTotal() + statsStoreVo.getOutCoinTotal());
            statsStoreVo.setOnLineOutCoinTotal(statsStoreVo2.getOnLineOutCoinTotal() + statsStoreVo.getOnLineOutCoinTotal());
            statsStoreVo.setOffLinePayOutCoinTotal(statsStoreVo2.getOffLinePayOutCoinTotal() + statsStoreVo.getOffLinePayOutCoinTotal());
            statsStoreVo.setInsertCoinTotal(statsStoreVo2.getInsertCoinTotal() + statsStoreVo.getInsertCoinTotal());
            statsStoreVo.setInsertCoinOnLine(statsStoreVo2.getInsertCoinOnLine() + statsStoreVo.getInsertCoinOnLine());
            statsStoreVo.setInsertCoinOffline(statsStoreVo2.getInsertCoinOffline() + statsStoreVo.getInsertCoinOffline());
            statsStoreVo.setGiftConsume(statsStoreVo2.getGiftConsume() + statsStoreVo.getGiftConsume());
            statsStoreVo.setGiftCost(statsStoreVo2.getGiftCost().add(statsStoreVo.getGiftCost()));
            statsStoreVo.setGiftOutRate(statsStoreVo2.getGiftOutRate().add(statsStoreVo.getGiftOutRate()));
            statsStoreVo.setIncomeCommodityTotal(statsStoreVo2.getIncomeCommodityTotal() + statsStoreVo.getIncomeCommodityTotal());
            statsStoreVo.setIncomeTotalIntegral(statsStoreVo2.getIncomeTotalIntegral() + statsStoreVo.getIncomeTotalIntegral());
            statsStoreVo.setExpendCommodityTotal(statsStoreVo2.getExpendCommodityTotal() + statsStoreVo.getExpendCommodityTotal());
            statsStoreVo.setExpendTotalIntegral(statsStoreVo2.getExpendTotalIntegral() + statsStoreVo.getExpendTotalIntegral());
            statsStoreVo.setTurnoverDouYin(statsStoreVo2.getTurnoverDouYin().add(statsStoreVo.getTurnoverDouYin()));
            statsStoreVo.setTurnoverMeiTuan(statsStoreVo2.getTurnoverMeiTuan().add(statsStoreVo.getTurnoverMeiTuan()));
            statsStoreVo.setScanCodePayTotalTurnover(statsStoreVo2.getScanCodePayTotalTurnover().add(statsStoreVo.getScanCodePayTotalTurnover()));
            statsStoreVo.setScanningFee(statsStoreVo2.getScanningFee().add(statsStoreVo.getScanningFee()));
            statsStoreVo.setTiktokCancellationFee(statsStoreVo2.getTiktokCancellationFee().add(statsStoreVo.getTiktokCancellationFee()));
            statsStoreVo.setMeiTuanCancellationFee(statsStoreVo2.getMeiTuanCancellationFee().add(statsStoreVo.getMeiTuanCancellationFee()));
            statsStoreVo.setIncomeTotalGameCoin(statsStoreVo2.getIncomeTotalGameCoin() +statsStoreVo.getIncomeTotalGameCoin() );
            statsStoreVo.setIncomeCommodityGameCoin(statsStoreVo2.getIncomeCommodityGameCoin() + statsStoreVo.getIncomeCommodityGameCoin());
            statsStoreVo.setStoredValueRechargeBalance(statsStoreVo2.getStoredValueRechargeBalance().add(statsStoreVo.getStoredValueRechargeBalance()));
            statsStoreVo.setStoredValueComplimentaryBalance(statsStoreVo2.getStoredValueComplimentaryBalance().add(statsStoreVo.getStoredValueRechargeBalance()));
            statsStoreVo.setConsumeRechargeBalance(statsStoreVo2.getConsumeRechargeBalance().add(statsStoreVo.getStoredValueRechargeBalance()));
            statsStoreVo.setConsumeComplimentaryBalance(statsStoreVo2.getConsumeComplimentaryBalance().add(statsStoreVo.getStoredValueRechargeBalance()));
            statsStoreVo.setMemberConsumeNum(statsStoreVo2.getMemberConsumeNum() + statsStoreVo.getMemberConsumeNum());
            statsStoreVo.setMemberConsumeNewNum(statsStoreVo2.getMemberConsumeNewNum() + statsStoreVo.getMemberConsumeNewNum());
            statsStoreVo.setMemberConsumeOldNum(statsStoreVo2.getMemberConsumeOldNum() + statsStoreVo.getMemberConsumeOldNum());
            statsStoreVo.setMaximumUnitPrice(statsStoreVo2.getMaximumUnitPrice().add(statsStoreVo.getMaximumUnitPrice()));
            statsStoreVo.setMinimumUnitPrice(statsStoreVo2.getMinimumUnitPrice().add(statsStoreVo.getMinimumUnitPrice()));
            statsStoreVo.setLeaveMemberPhoneNumber(statsStoreVo2.getLeaveMemberPhoneNumber());
            //总金额
            BigDecimal totalTurnover =  statsStoreVo.getTurnover().add(statsStoreVo2.getTurnover());
            //平均客价
            statsStoreVo.setAveragePrice(BigDecimal.ZERO);
            if(totalTurnover.compareTo(BigDecimal.ZERO)>0){
                //消费顾客
                Integer memberConsumeNum =  statsStoreVo.getMemberConsumeNum() + statsStoreVo2.getMemberConsumeNum();
                if(memberConsumeNum>0){
                    //计算平均价格
                    statsStoreVo.setAveragePrice(totalTurnover.divide(BigDecimal.valueOf(memberConsumeNum),2, BigDecimal.ROUND_HALF_UP));
                }
            }
            this.outConStorePercent(statsStoreVo);
            this.amountStorePercent(statsStoreVo);
        }
    }

    /**
     * 统计饼图本月数据（包含当天）
     * */
    private StatsStoreVo getThisMonthUser(StatsStoreDto statsStoreDto) {
        statsStoreDto.setType(StatisticsTypeEnum.DAY.getCode());
        StatsStoreVo storeVo = this.findFromStatsUser(statsStoreDto);
        //当天
        StatsStoreVo todayStatsUserVo = this.findTodayStatsUserFromOrder(statsStoreDto);
        this.statsUserVoAdd(storeVo, todayStatsUserVo);
        return storeVo;
    }
    /**
     * 合并总数据user
     * */
    private void statsUserVoAdd(StatsStoreVo returnStatsUserVo, StatsStoreVo todayStatsUserVo) {
         //门店套餐
        List<StatsUserVo> storePackageData = this.publicPackageData(returnStatsUserVo.getStatistStorePackageList(), todayStatsUserVo.getStatistStorePackageList());
        returnStatsUserVo.setStatistStorePackageList(storePackageData);

        //抖音套餐
        List<StatsUserVo> douYinPackageData = this.publicPackageData(returnStatsUserVo.getStatistDouYinPackageList(), todayStatsUserVo.getStatistDouYinPackageList());
        returnStatsUserVo.setStatistDouYinPackageList(douYinPackageData);

        //美团套餐
        List<StatsUserVo> meiTuanPackageData = this.publicPackageData(returnStatsUserVo.getStatistMeiTuanPackageList(), todayStatsUserVo.getStatistMeiTuanPackageList());
        returnStatsUserVo.setStatistDouYinPackageList(meiTuanPackageData);

        // 核实套票
        List<StatsUserVo> mergedData = this.mergeTicketUsageData(returnStatsUserVo.getStatistTicketUsageRecordList(), todayStatsUserVo.getStatistTicketUsageRecordList());
        returnStatsUserVo.setStatistTicketUsageRecordList(mergedData);

        //最高客单价
        Integer max = returnStatsUserVo.getMaximumUnitPrice().compareTo(todayStatsUserVo.getMaximumUnitPrice());
        returnStatsUserVo.setMaximumUnitPrice(max < 0 ? todayStatsUserVo.getMaximumUnitPrice() : returnStatsUserVo.getMaximumUnitPrice());
        //最低客单价
        Integer min = returnStatsUserVo.getMinimumUnitPrice().compareTo(todayStatsUserVo.getMinimumUnitPrice());
        returnStatsUserVo.setMinimumUnitPrice(min < 0 ? todayStatsUserVo.getMinimumUnitPrice() : returnStatsUserVo.getMinimumUnitPrice());
        returnStatsUserVo.setMemberConsumeNum(todayStatsUserVo.getMemberConsumeNum() + returnStatsUserVo.getMemberConsumeNum());
        returnStatsUserVo.setMemberConsumeNewNum(todayStatsUserVo.getMemberConsumeNewNum() + returnStatsUserVo.getMemberConsumeNewNum());
        returnStatsUserVo.setMemberConsumeOldNum(todayStatsUserVo.getMemberConsumeOldNum() + returnStatsUserVo.getMemberConsumeOldNum());

        returnStatsUserVo.setLeaveMemberPhoneNumber(todayStatsUserVo.getLeaveMemberPhoneNumber() + returnStatsUserVo.getLeaveMemberPhoneNumber());
        //平均值
        if(returnStatsUserVo.getTurnover().compareTo(BigDecimal.ZERO)>0 && todayStatsUserVo.getMemberConsumeNum() > 0){
            returnStatsUserVo.setAveragePrice(returnStatsUserVo.getTurnover().divide(BigDecimal.valueOf(returnStatsUserVo.getMemberConsumeNum()),2, BigDecimal.ROUND_HALF_UP));
        }else{
            returnStatsUserVo.setAveragePrice(BigDecimal.ZERO);
        }
        returnStatsUserVo.setTurnover(todayStatsUserVo.getTurnover().add(returnStatsUserVo.getTurnover()));
        returnStatsUserVo.setSettlementMoney(todayStatsUserVo.getSettlementMoney().add(returnStatsUserVo.getSettlementMoney()));
        returnStatsUserVo.setCashMoney(todayStatsUserVo.getCashMoney().add(returnStatsUserVo.getCashMoney()));
        returnStatsUserVo.setTurnoverDouYin(todayStatsUserVo.getTurnoverDouYin().add(returnStatsUserVo.getTurnoverDouYin()));
        returnStatsUserVo.setTurnoverMeiTuan(todayStatsUserVo.getTurnoverMeiTuan().add(returnStatsUserVo.getTurnoverMeiTuan()));
        returnStatsUserVo.setScanningFee(todayStatsUserVo.getScanningFee().add(returnStatsUserVo.getScanningFee()));
        returnStatsUserVo.setTiktokCancellationFee(todayStatsUserVo.getTiktokCancellationFee().add(returnStatsUserVo.getTiktokCancellationFee()));
        returnStatsUserVo.setMeiTuanCancellationFee(todayStatsUserVo.getMeiTuanCancellationFee().add(returnStatsUserVo.getMeiTuanCancellationFee()));
        returnStatsUserVo.setActivityTurnover(todayStatsUserVo.getActivityTurnover().add(returnStatsUserVo.getActivityTurnover()));
        returnStatsUserVo.setScanCodePayTotalTurnover(todayStatsUserVo.getScanCodePayTotalTurnover().add(returnStatsUserVo.getScanCodePayTotalTurnover()));

        returnStatsUserVo.setIncomeCommodityTotal(0);
        returnStatsUserVo.setIncomeTotalIntegral(0);
        returnStatsUserVo.setExpendCommodityTotal(0);
        returnStatsUserVo.setExpendTotalIntegral(0);
        returnStatsUserVo.setIncomeTotalGameCoin(0);
        returnStatsUserVo.setIncomeCommodityGameCoin(0);

        returnStatsUserVo.setStoredValueRechargeBalance(BigDecimal.ZERO);
        returnStatsUserVo.setStoredValueComplimentaryBalance(BigDecimal.ZERO);
        returnStatsUserVo.setConsumeRechargeBalance(BigDecimal.ZERO);
        returnStatsUserVo.setConsumeComplimentaryBalance(BigDecimal.ZERO);
        this.amountPercent(returnStatsUserVo);
    }

    private List<StatsUserVo> publicPackageData(List<StatsUserVo> list, List<StatsUserVo> todayList) {
        // 创建一个 HashMap 用于存储设备数据，键为设备编号
        Map<String, StatsUserVo> deviceMap = new HashMap<>();
        for (StatsUserVo data : list) {
            String key = data.getTitle();
            deviceMap.put(key, data);
        }
        for (StatsUserVo data : todayList) {
            // 合并数据
            String key = data.getTitle();
            deviceMap.merge(key, data, (existing, newData) -> {
                // 新建一个 ，更新收入为现有收入与新数据收入之和
                data.setPackagePayCount(existing.getPackagePayCount() + (newData.getPackagePayCount()));
                data.setPackageTotalAmount(existing.getPackageTotalAmount().add(newData.getPackageTotalAmount()));
                return data;
            });
        }

        // 将合并后的结果转换为列表
        List<StatsUserVo> resultList = new ArrayList<>(deviceMap.values());

        // 根据 packageTotalAmount 降序排序
        resultList.sort((d1, d2) -> d2.getPackageTotalAmount().compareTo(d1.getPackageTotalAmount()));

        return resultList;
    }

    private List<StatsUserVo> mergeTicketUsageData(List<StatsUserVo> statistTicketUsageRecordList, List<StatsUserVo> statistTicketUsageRecordList1) {
        // 创建一个 HashMap 用于存储设备数据，键为设备编号
        Map<String, StatsUserVo> deviceMap = new HashMap<>();

        // 处理今天的数据
        for (StatsUserVo data : statistTicketUsageRecordList) {
            // 将今天的套票核销添加到 Map 中
            String key = this.generateKey(data);
            deviceMap.put(key, data);
        }

        // 处理昨天的数据
        for (StatsUserVo data : statistTicketUsageRecordList1) {
            // 合并昨天的数据
            String key = this.generateKey(data);
            deviceMap.merge(key, data, (existing, newData) -> {
                // 新建一个 ，更新收入为现有收入与新数据收入之和
                int combinedNum = existing.getTotalTime() + newData.getTotalTime();
                data.setTotalTime(combinedNum);
                return data;
            });
        }

        // 将合并后的结果转换为列表并返回
        return new ArrayList<>(deviceMap.values());
    }
    // 生成唯一的key：commodityId_commodityStoreUpDownId_commodityProjectUpDownId
    private String generateKey(StatsUserVo data) {
        return String.format("%s_%s_%s", data.getCommodityId(), data.getCommodityStoreUpDownId(), data.getCommodityProjectUpDownId());
    }
    private StatsStoreVo findFromStatsUser(StatsStoreDto statsStoreDto) {
        //组装参数
        StatsUserDto statsUserDto = new StatsUserDto();
        statsUserDto.setStatsType(StatsTypeEnum.statsUser.getCode());
        statsUserDto.setUserInfo(statsStoreDto.getUserInfo());
        statsUserDto.setDayType(statsStoreDto.getDayType());
        statsUserDto.setEndDateStr(statsStoreDto.getEndDateStr());
        statsUserDto.setStartDateStr(statsStoreDto.getStartDateStr());
        statsUserDto.setType(statsStoreDto.getType());
        //接受数据
        StatsUserVo statsUserVo;
        StatsUserVo statsUserExchange;
        List<StatsPackageUserVo> statistAllPackageList;

        //子账号单独统计门店
        if (statsUserDto.getUserInfo().getRoleId().equals(RoleEnum.SUB_ACCOUNT.getRoleId())) {
            statsUserVo = statsUserDao.findSubAccountStatsUser(statsUserDto);
            statsUserExchange = null;
            statistAllPackageList = statsPackageUserDao.findSubAccountStatistPackageUserByUserId(statsUserDto);
        } else {
            statsUserVo = statsUserDao.findByUserId(statsUserDto);
            statsUserExchange = null;
            statistAllPackageList = statsPackageUserDao.findCurrentStatistPackageUserByUserId(statsUserDto);
        }
        StatsStoreVo returnStatsUserVo = new StatsStoreVo();

        List<StatsUserVo> usageRecordVoList = new ArrayList<>();
        returnStatsUserVo.setStatistTicketUsageRecordList(usageRecordVoList);
        this.typePackage(statistAllPackageList, returnStatsUserVo);

        returnStatsUserVo.setTurnover(statsUserVo.getTurnover());
        returnStatsUserVo.setSettlementMoney(statsUserVo.getSettlementMoney());
        returnStatsUserVo.setCashMoney(statsUserVo.getCashMoney());
        returnStatsUserVo.setTurnoverDouYin(statsUserVo.getTurnoverDouYin());
        returnStatsUserVo.setTurnoverMeiTuan(statsUserVo.getTurnoverMeiTuan());
        returnStatsUserVo.setScanningFee(statsUserVo.getScanningFee());
        returnStatsUserVo.setTiktokCancellationFee(statsUserVo.getTiktokCancellationFee());
        returnStatsUserVo.setMeiTuanCancellationFee(statsUserVo.getMeiTuanCancellationFee());
        //活动收入
        BigDecimal activityTurnover = statsUserVo.getSeckillMoney().add(statsUserVo.getGroupBookingMoney()).add(statsUserVo.getConsumptionOfRedEnvelopesMoney()).add(statsUserVo.getMemberOfTheStoredValueMoney());
        returnStatsUserVo.setActivityTurnover(activityTurnover);
        //扫码支付 = 线上扫码 + 线下扫码
        returnStatsUserVo.setScanCodePayTotalTurnover(statsUserVo.getTurnoverOnLine().add(statsUserVo.getTurnoverOfflineCollectionCode()));

        returnStatsUserVo.setGiftOutRate(statsUserVo.getGiftOutRate());
        returnStatsUserVo.setGiftCost(statsUserVo.getGiftCost());
        returnStatsUserVo.setGiftConsume(statsUserVo.getGiftConsume());

        //礼品回收和礼品兑换
        returnStatsUserVo.setIncomeCommodityTotal(0);
        returnStatsUserVo.setIncomeTotalIntegral(0);
        returnStatsUserVo.setExpendCommodityTotal(0);
        returnStatsUserVo.setExpendTotalIntegral(0);
        returnStatsUserVo.setIncomeTotalGameCoin(0);
        returnStatsUserVo.setIncomeCommodityGameCoin(0);

        returnStatsUserVo.setStoredValueComplimentaryBalance(statsUserVo.getStoredValueComplimentaryBalance());
        returnStatsUserVo.setStoredValueRechargeBalance(statsUserVo.getStoredValueRechargeBalance());
        returnStatsUserVo.setConsumeComplimentaryBalance(statsUserVo.getConsumeComplimentaryBalance());
        returnStatsUserVo.setConsumeRechargeBalance(statsUserVo.getConsumeRechargeBalance());

        returnStatsUserVo.setMemberConsumeNewNum(statsUserVo.getMemberConsumeNewNum());
        returnStatsUserVo.setMemberConsumeOldNum(statsUserVo.getMemberConsumeOldNum());
        returnStatsUserVo.setMemberConsumeNum(statsUserVo.getMemberConsumeNum());
        returnStatsUserVo.setMaximumUnitPrice(statsUserVo.getMaxTotalAmount());
        returnStatsUserVo.setMinimumUnitPrice(statsUserVo.getMinTotalAmount());
        returnStatsUserVo.setAveragePrice(statsUserVo.getAveragePrice());
        returnStatsUserVo.setLeaveMemberPhoneNumber(statsUserVo.getLeaveMemberPhoneNumber());

        if (statsUserDto.getDayType() <= 1 || statsUserDto.getDayType() == 4) {
            if (statsUserDto.getEndDateStr().equals(DateTimeUtils.getCurrentDateStr())) {
                return returnStatsUserVo;
            }
            this.amountPercent(returnStatsUserVo);
        }

        return returnStatsUserVo;
    }

    private void typePackage(List<StatsPackageUserVo> statistAllPackageList, StatsStoreVo returnStatsUserVo) {
        // 创建Map来管理不同套餐类型对应的列表
        Map<Integer, List<StatsUserVo>> packageTypeMap = new HashMap<>();
        packageTypeMap.put(StatsPackageStorePackageTypeEnum.STORE_PACKAGE.getCode(), new ArrayList<>());
        packageTypeMap.put(StatsPackageStorePackageTypeEnum.DOUYIN_PACKAGE.getCode(), new ArrayList<>());
        packageTypeMap.put(StatsPackageStorePackageTypeEnum.MEITUAN_PACKAGE.getCode(), new ArrayList<>());
        // 判断statistAllPackageList是否为空
        if (ObjectUtils.isNotEmpty(statistAllPackageList)) {
            for (StatsPackageUserVo packageVo : statistAllPackageList) {
                Integer packageType = packageVo.getPackageType();
                // 调用辅助方法来创建StatsUserVo并根据套餐类型添加到对应的列表中
                StatsUserVo statsUserVo = this.createStatsUserVo(packageVo);
                // 将创建的StatsUserVo对象添加到对应的套餐类型列表中
                if (packageTypeMap.containsKey(packageType)) {
                    packageTypeMap.get(packageType).add(statsUserVo);
                }
            }
        }
        // 获取并设置不同套餐类型的列表
        returnStatsUserVo.setStatistStorePackageList(packageTypeMap.get(StatsPackageStorePackageTypeEnum.STORE_PACKAGE.getCode()));
        returnStatsUserVo.setStatistDouYinPackageList(packageTypeMap.get(StatsPackageStorePackageTypeEnum.DOUYIN_PACKAGE.getCode()));
        returnStatsUserVo.setStatistMeiTuanPackageList(packageTypeMap.get(StatsPackageStorePackageTypeEnum.MEITUAN_PACKAGE.getCode()));
    }

    private StatsUserVo createStatsUserVo(StatsPackageUserVo s) {
        StatsUserVo statsUserVo = new StatsUserVo();
        statsUserVo.setTitle(s.getTitle());
        statsUserVo.setPackagePayCount(s.getPayCount());
        statsUserVo.setPackageTotalAmount(s.getTotalAmount());
        return statsUserVo;
    }

    private List<StatsStoreVo> findFromStatsStoreV2(StatsStoreDto statsStoreDto) {
        List<StatsStoreVo> returnStatsStoreVosList = new ArrayList<>();
        List<MerchantStoreVo> merchantStoreVoList = merchantStoreService.findMerchantStoreIdByUserId(statsStoreDto.getUserInfo());
        List<StatsStoreVo> statsStoreVoList = statsStoreDao.findStoreStats(statsStoreDto);
        // 使用Map集合可以避免双重循环提高效率
        Map<Integer, StatsStoreVo> statsStoreVoMap = statsStoreVoList.stream().collect(Collectors.toMap(StatsStoreVo::getMchStoreId, v -> v));
        for (MerchantStoreVo merchantStoreVo : merchantStoreVoList) {
            StatsStoreVo storeVo = statsStoreVoMap.get(merchantStoreVo.getId());
            if(ObjectUtils.isEmpty(storeVo)){
                //初始化数据
                storeVo = new StatsStoreVo();
                this.initStoreData(storeVo);
            }
            storeVo.setMchStoreId(merchantStoreVo.getId());
            storeVo.setStoreName(merchantStoreVo.getStoreName());
            BigDecimal activityTurnover = storeVo.getSeckillMoney().add(storeVo.getGroupBookingMoney()).add(storeVo.getConsumptionOfRedEnvelopesMoney()).add(storeVo.getMemberOfTheStoredValueMoney());
            storeVo.setActivityTurnover(activityTurnover);
            Integer onLineOutCoinTotal = storeVo.getOutCoinTotal() - storeVo.getOffLinePayOutCoinTotal();
            storeVo.setOnLineOutCoinTotal(onLineOutCoinTotal);
            //扫码支付 = 线上扫码 + 线下扫码
            storeVo.setScanCodePayTotalTurnover(storeVo.getTurnoverOnLine().add(storeVo.getTurnoverOfflineCollectionCode()));
            //微信核销总出币 = 微信秒杀核销+微信拼团核销+微信凭证核销
            storeVo.setWeiXinVerifyTotalCoin(
                    storeVo.getWeiXinVoucherOutCoinTotal()
                            +storeVo.getWeiXinSeckillOutCoinTotal()
                            +storeVo.getWeiXinGroupBuyingOutCoinTotal());
            //售币总额turnoverGameCoin
            storeVo.setTurnoverGameCoin(storeVo.getTurnoverGameCoin()
                    .add(activityTurnover)
                    .add(storeVo.getTurnoverMeiTuan())
                    .add(storeVo.getTurnoverDouYin()));
            //币均价 = 售币总额 / 售币数
            if(storeVo.getTurnoverGameCoin().compareTo(BigDecimal.ONE) > -1 &&
                    storeVo.getQuantityOfCoinsSold().compareTo(1) > -1){
                BigDecimal total = storeVo.getTurnoverGameCoin().divide(new BigDecimal(storeVo.getQuantityOfCoinsSold()), 4, BigDecimal.ROUND_HALF_UP);
                storeVo.setAverageCoinPrice(total.setScale(2, BigDecimal.ROUND_HALF_UP));
            }else{
                storeVo.setAverageCoinPrice(BigDecimal.ZERO);
            }
            //礼品回收统计 礼品兑换统计
            statsStoreDto.setMchStoreId(merchantStoreVo.getId());
            storeVo.setIncomeCommodityTotal(0);
            storeVo.setIncomeTotalIntegral(0);
            storeVo.setExpendCommodityTotal(0);
            storeVo.setExpendTotalIntegral(0);
            storeVo.setIncomeTotalGameCoin(0);
            storeVo.setIncomeCommodityGameCoin(0);

            StatsStoreVo statsStoreVo = statsStoreDao.findStoreStatsCustomer(statsStoreDto);
            storeVo.setMemberConsumeNum(statsStoreVo.getMemberConsumeNum());
            storeVo.setMemberConsumeNewNum(statsStoreVo.getMemberConsumeNewNum());
            storeVo.setMemberConsumeOldNum(statsStoreVo.getMemberConsumeOldNum());
            storeVo.setMemberNewNum(statsStoreVo.getMemberNewNum());
            storeVo.setMaximumUnitPrice(statsStoreVo.getMaxTotalAmount());
            storeVo.setMinimumUnitPrice(statsStoreVo.getMinTotalAmount());
            storeVo.setAveragePrice(statsStoreVo.getAveragePrice());
            storeVo.setLeaveMemberPhoneNumber(statsStoreVo.getLeaveMemberPhoneNumber());

            storeVo.setGiftOutRate(storeVo.getGiftOutRate());
            storeVo.setGiftCost(storeVo.getGiftCost());
            storeVo.setGiftConsume(storeVo.getGiftConsume());

            /**
             * 查询套餐
             * */
            StatsUserDto statsUserDto = new StatsUserDto();
            statsUserDto.setStatsType(StatsTypeEnum.statsUser.getCode());
            statsUserDto.setUserInfo(statsStoreDto.getUserInfo());
            statsUserDto.setEndDateStr(statsStoreDto.getEndDateStr());
            statsUserDto.setStartDateStr(statsStoreDto.getStartDateStr());
            statsUserDto.setType(statsStoreDto.getType());
            statsUserDto.setMchStoreId(merchantStoreVo.getId());
            List<StatsPackageUserVo> statsPackageStoreVoList = statsPackageStoreDao.findStatsPackageStoreByMchStoreIdV2(statsUserDto);
            storeVo.setStatistTicketUsageRecordList(new ArrayList<>());
            this.typePackage(statsPackageStoreVoList, storeVo);

            if ((statsStoreDto.getDayType() <= 1 || statsStoreDto.getDayType() == 4) &&
                    !statsStoreDto.getEndDateStr().equals(DateTimeUtils.getCurrentDateStr())) {
                this.amountPercent(storeVo);
                this.outConPercent(storeVo);
            }
            returnStatsStoreVosList.add(storeVo);
        }
        return returnStatsStoreVosList;
    }

    private List<StatsStoreVo> findTodayStatsStoreFromOrderV2(StatsStoreDto statsStoreDto) {
        if (ObjectUtils.isNotEmpty(statsStoreDto.getHour())) {
            //获取昨天的开始时间和结束时间 格式yyyy-MM-dd HH:mm:ss
            statsStoreDto.setStartTime(DateTimeUtils.parseLocalDate(DateTimeUtils.getYesterday()).format(DateTimeUtils.START_DATETIME_FORMATTER));
            statsStoreDto.setEndTime(DateTimeUtils.parseLocalDate(DateTimeUtils.getYesterday()).format(DateTimeUtils.END_DATETIME_FORMATTER));
        } else {
            statsStoreDto.setStartTime(DateTimeUtils.getTodayStartTime());
            statsStoreDto.setEndTime(DateTimeUtils.getTodayEndTime());
        }
        //数据
        List<StatsStoreVo> statsStoreVoList = statsStoreDao.findOrderStatisticsGroupByStore(statsStoreDto);
        //查询所有的场地
        List<MerchantStoreVo> merchantStoreVoList = merchantStoreService.findMerchantStoreIdByUserId(statsStoreDto.getUserInfo());
        // 使用Map集合可以避免双重循环提高效率
        Map<Integer, StatsStoreVo> statsStoreVoMap = statsStoreVoList.stream().collect(Collectors.toMap(StatsStoreVo::getMchStoreId, v -> v));
        List<StatsStoreVo> returnStatsStoreList = new ArrayList<>();
        for (MerchantStoreVo merchantStoreVo : merchantStoreVoList) {
            log.info("场地ID{}：",merchantStoreVo.getId());
            StatsStoreVo storeVo = statsStoreVoMap.get(merchantStoreVo.getId());
            if(ObjectUtils.isEmpty(storeVo)){
                //初始化数据
                storeVo = new StatsStoreVo();
                this.initStoreData(storeVo);
            }
            storeVo.setMchStoreId(merchantStoreVo.getId());
            storeVo.setStoreName(merchantStoreVo.getStoreName());
            statsStoreDto.setConsumeRecordTypeIdArray(statsStoreDto.getInsertCoinConsumeRecordTypeIdArray());
            statsStoreDto.setMchStoreId(storeVo.getMchStoreId());
            //线上出币
            storeVo.setOnLinePayOutCoinTotal(0);
            // 出币合计 = 线上出币 + 现金出币
            storeVo.setOutCoinTotal(0);
            // 线上出币 = 在线支付出币 + 会员取币 + 微信核销 + 美团核销 + 抖音核销
            storeVo.setOnLineOutCoinTotal(0);
            // 现金出币 = 纸钞出币 + 1元硬币出币
            storeVo.setOffLinePayOutCoinTotal(0);
            //会员出币
            storeVo.setFetchMemberOutCoinTotal(0);
            //微信秒杀核销
            storeVo.setWeiXinSeckillOutCoinTotal(0);
            //微信拼团核销
            storeVo.setWeiXinGroupBuyingOutCoinTotal(0);
            //微信凭证核销
            storeVo.setWeiXinVoucherOutCoinTotal(0);
            //微信核销总出币 = 微信秒杀核销+微信拼团核销+微信凭证核销
            storeVo.setWeiXinVerifyTotalCoin(0);
            //人工出币
            storeVo.setArtificialOutCoinTotal(0);
            //游戏币红包币
            storeVo.setGameCoinRedPacketCoinTotal(0);
            //加群福利币
            storeVo.setGroupBenefitCoinTotal(0);
            //派发福利币
            storeVo.setDistributeBenefitCoinTotal(0);
            //售币数（游戏币销售数量）
            storeVo.setQuantityOfCoinsSold(0);
            //出币数（游戏币消耗数量）
            storeVo.setAmountOfCoinsConsumed(0);
            //余币数 = 售币数-消耗数
            storeVo.setRemainingCoins(0);

            // 投币合计 = 线上投币 + 线下投币
            storeVo.setInsertCoinTotal(0);
            // 线上投币
            storeVo.setInsertCoinOnLine(0);
            // 线下投币
            storeVo.setInsertCoinOffline(0);
            storeVo.setFetchMemberOutCoinTotal(0);
            storeVo.setDouYinOutCoinTotal(0);
            storeVo.setMeiTuanOutCoinTotal(0);

            //当天的投币消费记录数，count值
            statsStoreDto.setConsumeRecordTypeId(ConsumeRecordTypeEnum.CONSUME.getCode());
            storeVo.setGiftOutRate(BigDecimal.ZERO);
            storeVo.setGiftCost(BigDecimal.ZERO);
            storeVo.setGiftConsume(0);

            //根据场地查询 当天新会员数量
            Integer newNum = memberStoreBalanceService.findMemberNewNumByStoreId(statsStoreDto);
            storeVo.setMemberConsumeNewNum(newNum);
            //根据场地查询 当天老会员数量
            Integer oldNum = memberStoreBalanceService.findMemberOldNumByStoreId(statsStoreDto);
            storeVo.setMemberConsumeOldNum(oldNum);


            //查询当天消费顾客
            StatsStoreVo statsUserVo = statsStoreDao.findCustomerCount(statsStoreDto);

            //消费会员个数：现金笔数 + 抖音核销笔数 + 美团核销笔数。注意：现金笔数按memberId为空的来计算
            storeVo.setMemberConsumeNum(newNum + oldNum +
                    statsUserVo.getCashCount()+
                    statsUserVo.getMeiTuanCount()+
                    statsUserVo.getDouYinCount());

            //活动
            storeVo.setActivityTurnover(BigDecimal.ZERO);
            storeVo.setTurnover(storeVo.getTurnover().add(BigDecimal.ZERO));
            storeVo.setSettlementMoney(storeVo.getSettlementMoney().add(BigDecimal.ZERO));

            // 游戏币营业额，通用商品营业额，套票商品营业额
            StatsStoreVo statsStoreCommodity = statsStoreDao.findCommodityTypeByStoreIdTurnover(statsStoreDto);
            storeVo.setTurnoverGameCoin(statsStoreCommodity.getTurnoverGameCoin()
                    .add(storeVo.getActivityTurnover())
                    .add(storeVo.getTurnoverMeiTuan())
                    .add(storeVo.getTurnoverDouYin()));
            //币均价 = 售币总额 / 售币数
            if(storeVo.getTurnoverGameCoin().compareTo(BigDecimal.ONE) > -1 &&
                    storeVo.getQuantityOfCoinsSold().compareTo(1) > -1){
                BigDecimal total = storeVo.getTurnoverGameCoin().divide(new BigDecimal(storeVo.getQuantityOfCoinsSold()), 4, BigDecimal.ROUND_HALF_UP);
                storeVo.setAverageCoinPrice(total.setScale(2, BigDecimal.ROUND_HALF_UP));
            }else{
                storeVo.setAverageCoinPrice(BigDecimal.ZERO);
            }

            //最高客单价
            Integer max = statsUserVo.getMaxTotalAmount().compareTo(BigDecimal.ZERO);
            storeVo.setMaximumUnitPrice(max<0?BigDecimal.ZERO:statsUserVo.getMaxTotalAmount());
            //最低客单价
            Integer min = statsUserVo.getMinTotalAmount().compareTo(BigDecimal.ZERO);
            storeVo.setMinimumUnitPrice(min<0?BigDecimal.ZERO:statsUserVo.getMinTotalAmount());

            //平均客价
            if(storeVo.getTurnover().compareTo(BigDecimal.ZERO) > 0 && storeVo.getMemberConsumeNum() > 0){
                storeVo.setAveragePrice(storeVo.getTurnover().divide(BigDecimal.valueOf(storeVo.getMemberConsumeNum()),2, BigDecimal.ROUND_HALF_UP));
            }else{
                storeVo.setAveragePrice(BigDecimal.ZERO);
            }
            //根据场地 留存手机号会员数量
            Integer countPhoneNumber = memberDao.findCountMemberByMchStoreId(statsStoreDto);
            storeVo.setLeaveMemberPhoneNumber(countPhoneNumber);

            /**
             * 查询套餐
             * statsUserDto
             * */
            StatsUserDto statsUserDto = new StatsUserDto();
            statsUserDto.setUserInfo(statsStoreDto.getUserInfo());
            statsUserDto.setMchStoreId(storeVo.getMchStoreId());
            statsUserDto.setStartTime(DateTimeUtils.getTodayStartTime());
            statsUserDto.setEndTime(DateTimeUtils.getTodayEndTime());
            //门店套餐
            List<StatsUserVo> statistStorePackageList = statsUserDao.findOrderStatistStorePackageV2(statsUserDto);
            storeVo.setStatistStorePackageList(statistStorePackageList);

            //抖音套餐
            storeVo.setStatistDouYinPackageList(new ArrayList<>());

            //美团套餐
            storeVo.setStatistMeiTuanPackageList(new ArrayList<>());

            //套票核销
            storeVo.setStatistTicketUsageRecordList(new ArrayList<>());
            if (statsStoreDto.getDayType() == 0 || statsStoreDto.getDayType() == 1){
                this.amountPercent(storeVo);
                this.outConPercent(storeVo);
            }
            returnStatsStoreList.add(storeVo);
        }
        return returnStatsStoreList;
    }

    private void initStoreData(StatsStoreVo storeVo) {
        storeVo.setTurnover(BigDecimal.valueOf(0));
        storeVo.setSettlementMoney(BigDecimal.valueOf(0));
        storeVo.setCashMoney(BigDecimal.valueOf(0));
        storeVo.setTurnoverOnLine(BigDecimal.valueOf(0));
        storeVo.setActivityTurnover(BigDecimal.valueOf(0));
        storeVo.setOutCoinTotal(0);
        storeVo.setOnLineOutCoinTotal(0);
        storeVo.setOnLinePayOutCoinTotal(0);
        storeVo.setOffLinePayOutCoinTotal(0);
        storeVo.setInsertCoinTotal(0);
        storeVo.setInsertCoinOnLine(0);
        storeVo.setInsertCoinOffline(0);
        storeVo.setGiftConsume(0);
        storeVo.setGiftCost(BigDecimal.valueOf(0));
        storeVo.setGiftOutRate(BigDecimal.valueOf(0));
        storeVo.setIncomeCommodityTotal(0);
        storeVo.setIncomeTotalIntegral(0);
        storeVo.setExpendCommodityTotal(0);
        storeVo.setExpendTotalIntegral(0);
        storeVo.setTurnoverDouYin(BigDecimal.valueOf(0));
        storeVo.setTurnoverMeiTuan(BigDecimal.valueOf(0));
        storeVo.setFetchMemberOutCoinTotal(0);
        storeVo.setDouYinOutCoinTotal(0);
        storeVo.setMeiTuanOutCoinTotal(0);
        storeVo.setFetchMemberOutCoinTotal(0);
        storeVo.setWeiXinVerifyTotalCoin(0);
        storeVo.setWeiXinSeckillOutCoinTotal(0);
        storeVo.setWeiXinGroupBuyingOutCoinTotal(0);
        storeVo.setWeiXinVoucherOutCoinTotal(0);
        storeVo.setArtificialOutCoinTotal(0);
        storeVo.setGameCoinRedPacketCoinTotal(0);
        storeVo.setGroupBenefitCoinTotal(0);
        storeVo.setDistributeBenefitCoinTotal(0);
        storeVo.setQuantityOfCoinsSold(0);
        storeVo.setAmountOfCoinsConsumed(0);
        storeVo.setRemainingCoins(0);
        storeVo.setAverageCoinPrice(BigDecimal.ZERO);
        storeVo.setTurnoverGameCoin(BigDecimal.ZERO);
        storeVo.setTurnoverOfflineCollectionCode(BigDecimal.ZERO);
        storeVo.setScanCodePayTotalTurnover(BigDecimal.ZERO);
        storeVo.setScanningFee(BigDecimal.ZERO);
        storeVo.setTiktokCancellationFee(BigDecimal.ZERO);
        storeVo.setMeiTuanCancellationFee(BigDecimal.ZERO);
        storeVo.setIncomeTotalGameCoin(0);
        storeVo.setIncomeCommodityGameCoin(0);
        storeVo.setStoredValueRechargeBalance(BigDecimal.ZERO);
        storeVo.setStoredValueComplimentaryBalance(BigDecimal.ZERO);
        storeVo.setConsumeRechargeBalance(BigDecimal.ZERO);
        storeVo.setConsumeComplimentaryBalance(BigDecimal.ZERO);
        storeVo.setSeckillMoney(BigDecimal.ZERO);
        storeVo.setGroupBookingMoney(BigDecimal.ZERO);
        storeVo.setConsumptionOfRedEnvelopesMoney(BigDecimal.ZERO);
        storeVo.setMemberOfTheStoredValueMoney(BigDecimal.ZERO);
    }

    /**
     * 查找当天的统计
     *
     * @param statsStoreDto
     * @return
     */
    private StatsStoreVo findTodayStatsUserFromOrder(StatsStoreDto statsStoreDto) {
        log.info("时间分支参数{}",statsStoreDto.getDayType());
        //组装参数
        StatsUserDto statsUserDto = new StatsUserDto();
        statsUserDto.setStatsType(StatsTypeEnum.statsUser.getCode());
        statsUserDto.setUserInfo(statsStoreDto.getUserInfo());
        statsUserDto.setDayType(statsStoreDto.getDayType());
        if(ObjectUtils.isNotEmpty(statsUserDto.getHour())){
            //获取昨天的开始时间和结束时间 格式yyyy-MM-dd HH:mm:ss
            statsUserDto.setStartTime(DateTimeUtils.parseLocalDate(DateTimeUtils.getYesterday()).format(DateTimeUtils.START_DATETIME_FORMATTER));
            statsUserDto.setEndTime(DateTimeUtils.parseLocalDate(DateTimeUtils.getYesterday()).format(DateTimeUtils.END_DATETIME_FORMATTER));
        }else{
            statsUserDto.setStartTime(DateTimeUtils.getTodayStartTime());
            statsUserDto.setEndTime(DateTimeUtils.getTodayEndTime());
        }

        //返回值
        StatsStoreVo returnStatsUserVo = new StatsStoreVo();

        //普通订单
        StatsUserVo statsUserVo = statsUserDao.findOrderStatistics(statsUserDto);
        returnStatsUserVo.setScanCodePayTotalTurnover(statsUserVo.getScanCodePayTotalTurnover());
        returnStatsUserVo.setCashMoney(statsUserVo.getCashMoney());
        returnStatsUserVo.setTurnoverDouYin(statsUserVo.getTurnoverDouYin());
        returnStatsUserVo.setTurnoverMeiTuan(statsUserVo.getTurnoverMeiTuan());
        returnStatsUserVo.setScanningFee(statsUserVo.getScanningFee());
        returnStatsUserVo.setTiktokCancellationFee(statsUserVo.getTiktokCancellationFee());
        returnStatsUserVo.setMeiTuanCancellationFee(statsUserVo.getMeiTuanCancellationFee());
        returnStatsUserVo.setActivityTurnover(BigDecimal.ZERO);
        //营业额
        returnStatsUserVo.setTurnover(statsUserVo.getTurnover().add(BigDecimal.ZERO));
        //结算额
        returnStatsUserVo.setSettlementMoney(statsUserVo.getSettlementMoney().add(BigDecimal.ZERO));

        //出礼百分比率
        BigDecimal rate = BigDecimal.ZERO;
        BigDecimal percentage = rate.multiply(new BigDecimal("100"));
        returnStatsUserVo.setGiftOutRate(percentage);
        returnStatsUserVo.setGiftCost(BigDecimal.ZERO);
        returnStatsUserVo.setGiftConsume(0);

        //TODO 注意：现金笔数、抖音核销笔数、美团核销笔数先不按memberId为空的来计算，后期需求再优化

        // 消费新顾客数
        Integer newNum = memberStoreBalanceService.findDayMemberNewNumByUserId(statsUserDto);
        // 现金笔数 + 抖音核销笔数 + 美团核销笔数
        returnStatsUserVo.setMemberConsumeNewNum(
                newNum +
                statsUserVo.getCashCount() +
                statsUserVo.getMeiTuanCount() +
                statsUserVo.getDouYinCount()
        );
        // 消费老顾客数
        Integer oldNum = memberStoreBalanceService.findDayMemberOldNumByUserId(statsUserDto);
        returnStatsUserVo.setMemberConsumeOldNum(oldNum);
        //消费顾客 消费新顾客数 + 消费老顾客数。
        returnStatsUserVo.setMemberConsumeNum(returnStatsUserVo.getMemberConsumeNewNum() + returnStatsUserVo.getMemberConsumeOldNum());

        //最高客单价
        Integer max = statsUserVo.getMaxTotalAmount().compareTo(BigDecimal.ZERO);
        returnStatsUserVo.setMaximumUnitPrice(max < 0 ? BigDecimal.ZERO : statsUserVo.getMaxTotalAmount());
        //最低客单价
        Integer min = statsUserVo.getMinTotalAmount().compareTo(BigDecimal.ZERO);
        log.info("普通订单最小金额{}：",statsUserVo.getMinTotalAmount());
        log.info("活动订单最小金额{}：",BigDecimal.ZERO);
        returnStatsUserVo.setMinimumUnitPrice(min < 0 ? BigDecimal.ZERO : statsUserVo.getMinTotalAmount());
        //平均客价
        if (statsUserVo.getTurnover().compareTo(BigDecimal.ZERO) > 0 && statsUserVo.getMemberConsumeNum() > 0) {
            returnStatsUserVo.setAveragePrice(statsUserVo.getTurnover().divide(BigDecimal.valueOf(statsUserVo.getMemberConsumeNum()), 2, BigDecimal.ROUND_HALF_UP));
        } else {
            returnStatsUserVo.setAveragePrice(BigDecimal.ZERO);
        }
        //留存手机号会员数量
        Integer countPhoneNumber = memberDao.findCountByMemberId(statsUserDto);
        returnStatsUserVo.setLeaveMemberPhoneNumber(countPhoneNumber);

        //门店套餐
        List<StatsUserVo> statistStorePackageList = statsUserDao.findOrderStatistStorePackageV2(statsUserDto);
        returnStatsUserVo.setStatistStorePackageList(statistStorePackageList);

        //抖音套餐
        returnStatsUserVo.setStatistDouYinPackageList(new ArrayList<>());

        //美团套餐
        returnStatsUserVo.setStatistMeiTuanPackageList(new ArrayList<>());

        //套票核销
        returnStatsUserVo.setStatistTicketUsageRecordList(new ArrayList<>());

        //计算出币的占比
        //dayType：0当天 1昨天（夜间统计的时候点击昨天调用实时统计也要算百分比）
        if (statsUserDto.getDayType() == 0 || statsUserDto.getDayType() == 1){;
            this.amountPercent(returnStatsUserVo);
        }
        return returnStatsUserVo;

    }
    //计算币占比
    private void outConPercent(StatsStoreVo statsStoreVo) {
        //初始化
        BigDecimal rate = new BigDecimal(0);
        statsStoreVo.setPercentOffLinePayOutCoin(rate);
        statsStoreVo.setPercentFetchMemberOutCoin(rate);
        statsStoreVo.setPercentOnLinePayOutCoinTotal(rate);
        statsStoreVo.setPercentOnLinePayOutCoinTotal(rate);
        statsStoreVo.setPercentArtificialOutCoin(rate);
        statsStoreVo.setPercentMeiTuanOutCoin(rate);
        statsStoreVo.setPercentDouYinOutCoin(rate);
        statsStoreVo.setPercentWeiXinVerifyOutCoin(rate);
        statsStoreVo.setPercentInsertCoinOffline(rate);
        statsStoreVo.setPercentInsertCoinOnLine(rate);
        statsStoreVo.setPercentDistributeBenefitCoin(rate);
        statsStoreVo.setPercentCoinRedPacketCoin(rate);
        //购币情况
        if(statsStoreVo.getOutCoinTotal() > 0){
            //BigDecimal total = new BigDecimal(statsUserVo.getQuantityOfCoinsSold());
            BigDecimal total = new BigDecimal(statsStoreVo.getOutCoinTotal());
            // 现金出币 除以 总出币 保留两位小数 乘 100
            BigDecimal offLinePayOutCoinTotal = new BigDecimal(statsStoreVo.getOffLinePayOutCoinTotal());
            BigDecimal offLinePayOutCoinTotalRate = offLinePayOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentOffLinePayOutCoin(offLinePayOutCoinTotalRate.multiply(new BigDecimal("100")));

            //线上出币
            BigDecimal linePayOutCoinTotal = new BigDecimal(statsStoreVo.getOnLinePayOutCoinTotal());
            BigDecimal linePayOutCoinTotalRate = linePayOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentOnLinePayOutCoinTotal(linePayOutCoinTotalRate.multiply(new BigDecimal("100")));

            //会员取币
            BigDecimal fetchMemberOutCoinTotal = new BigDecimal(statsStoreVo.getFetchMemberOutCoinTotal());
            BigDecimal fetchMemberOutCoinTotalRate = fetchMemberOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentFetchMemberOutCoin(fetchMemberOutCoinTotalRate.multiply(new BigDecimal("100")));

            //抖音核销出币
            BigDecimal douYinOutCoinTotal = new BigDecimal(statsStoreVo.getDouYinOutCoinTotal());
            BigDecimal douYinOutCoinTotalRate = douYinOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentDouYinOutCoin(douYinOutCoinTotalRate.multiply(new BigDecimal("100")));

            //美团核销出币
            BigDecimal meiTuanOutCoinTotal = new BigDecimal(statsStoreVo.getMeiTuanOutCoinTotal());
            BigDecimal meiTuanOutCoinTotalRate = meiTuanOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentMeiTuanOutCoin(meiTuanOutCoinTotalRate.multiply(new BigDecimal("100")));

            //微信核销出币
            BigDecimal weiXinVerifyOutCoinTotal = new BigDecimal(statsStoreVo.getWeiXinVerifyTotalCoin());
            BigDecimal weiXinVerifyOutCoinTotalRate = weiXinVerifyOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentWeiXinVerifyOutCoin(weiXinVerifyOutCoinTotalRate.multiply(new BigDecimal("100")));

            //人工出币
            BigDecimal artificialOutCoinTotal = new BigDecimal(statsStoreVo.getArtificialOutCoinTotal());
            BigDecimal artificialOutCoinTotalRate = artificialOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentArtificialOutCoin(artificialOutCoinTotalRate.multiply(new BigDecimal("100")));

            //游戏币红包币
            BigDecimal gameCoinRedPacketCoinTotal = new BigDecimal(statsStoreVo.getGameCoinRedPacketCoinTotal());
            BigDecimal gameCoinRedPacketCoinTotalRate = gameCoinRedPacketCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentCoinRedPacketCoin(gameCoinRedPacketCoinTotalRate.multiply(new BigDecimal("100")));
            //加群福利币
            BigDecimal groupBenefitCoinTotal = new BigDecimal(statsStoreVo.getGroupBenefitCoinTotal());
            BigDecimal groupBenefitCoinTotalRate = groupBenefitCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentGroupBenefitCoin(groupBenefitCoinTotalRate.multiply(new BigDecimal("100")));

            //派发福利币
            BigDecimal distributeBenefitCoinTotal = new BigDecimal(statsStoreVo.getDistributeBenefitCoinTotal());
            BigDecimal distributeBenefitCoinTotalRate = distributeBenefitCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentDistributeBenefitCoin(distributeBenefitCoinTotalRate.multiply(new BigDecimal("100")));

        }

        //投币情况
        if(statsStoreVo.getInsertCoinTotal() > 0){
            BigDecimal total = new BigDecimal(statsStoreVo.getInsertCoinTotal());
            //线上投币
            BigDecimal insertCoinOnLine = new BigDecimal(statsStoreVo.getInsertCoinOnLine());
            BigDecimal insertCoinOnLineRate = insertCoinOnLine.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentInsertCoinOnLine(insertCoinOnLineRate.multiply(new BigDecimal("100")));

            //线下投币
            BigDecimal insertCoinOffline = new BigDecimal(statsStoreVo.getInsertCoinOffline());
            BigDecimal insertCoinOfflineRate = insertCoinOffline.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsStoreVo.setPercentInsertCoinOffline(insertCoinOfflineRate.multiply(new BigDecimal("100")));
        }
    }
    private void amountPercent(StatsStoreVo statsStoreVo) {
        BigDecimal money = new BigDecimal(0);
        statsStoreVo.setPercentCashMoney(money);
        statsStoreVo.setPercentActivityTurnover(money);
        statsStoreVo.setPercentTurnoverOnLine(money);
        statsStoreVo.setPercentTurnoverMeiTuan(money);
        statsStoreVo.setPercentTurnoverDouYin(money);
        if (statsStoreVo.getTurnover().compareTo(BigDecimal.ZERO) > 0) {
            ArrayList<BigDecimal> percentList = new ArrayList<>();
            //现金收款 除以 总营业额 保留两位小数 乘 100
            BigDecimal percentCashMoney = statsStoreVo.getCashMoney().divide(statsStoreVo.getTurnover(), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            statsStoreVo.setPercentCashMoney(percentCashMoney);
            percentList.add(percentCashMoney);
            // 活动总结算额 除以 总营业额 保留两位小数 乘 100
            BigDecimal activityTurnover1 = statsStoreVo.getActivityTurnover().divide(statsStoreVo.getTurnover(), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            statsStoreVo.setPercentActivityTurnover(activityTurnover1);
            percentList.add(activityTurnover1);

            // 线上营业额  除以 总营业额 保留两位小数 乘 100
            BigDecimal percentTurnoverOnLine = statsStoreVo.getScanCodePayTotalTurnover().divide(statsStoreVo.getTurnover(), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            statsStoreVo.setPercentTurnoverOnLine(percentTurnoverOnLine);
            percentList.add(percentTurnoverOnLine);

            //抖音收款
            BigDecimal percentTurnoverDouYin = statsStoreVo.getTurnoverDouYin().divide(statsStoreVo.getTurnover(), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            statsStoreVo.setPercentTurnoverDouYin(percentTurnoverDouYin);
            percentList.add(percentTurnoverDouYin);

            //美团收款
            BigDecimal percentTurnoverMeiTuan = statsStoreVo.getTurnoverMeiTuan().divide(statsStoreVo.getTurnover(), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            statsStoreVo.setPercentTurnoverMeiTuan(percentTurnoverMeiTuan);
            percentList.add(percentTurnoverMeiTuan);
            BigDecimal maxPercent = Collections.max(percentList);
            BigDecimal bfb = new BigDecimal(100);
            //0是现金，1是活动...
            Integer index = -1;
            boolean flog = true;
            if(maxPercent.compareTo(BigDecimal.ZERO) == 1){
                for(int i = 0; i < percentList.size(); i++){
                    if(percentList.get(i).compareTo(maxPercent) == 0 && flog){
                        //记录最大百分比坐标
                        index = i;
                        flog = false;
                        continue;
                    }
                    bfb = bfb.subtract(percentList.get(i));
                }
                switch (index){
                    case 0:
                        statsStoreVo.setPercentCashMoney(bfb);
                        break;
                    case 1:
                        statsStoreVo.setPercentActivityTurnover(bfb);
                        break;
                    case 2:
                        statsStoreVo.setPercentTurnoverOnLine(bfb);
                        break;
                    case 3:
                        statsStoreVo.setPercentTurnoverDouYin(bfb);
                        break;
                    case 4:
                        statsStoreVo.setPercentTurnoverMeiTuan(bfb);
                        break;
                }
            }
        }
    }

    @Override
    public ServerResponse findStatsStoreBranchHead(StatsStoreDto statsStoreDto) throws ExecutionException, InterruptedException {
        final ServerResponse serverResponse = this.commonCheck(statsStoreDto);
        if(!serverResponse.getIsSuccess()){
            return serverResponse;
        }
        CompletableFuture<StatsStoreVo> todayFuture = CompletableFuture.supplyAsync(() -> {
            StatsStoreVo todayStatsStoreVo = new StatsStoreVo();
            todayStatsStoreVo.setCashMoney(BigDecimal.ZERO);
            todayStatsStoreVo.setTurnoverDouYin(BigDecimal.ZERO);
            todayStatsStoreVo.setTurnoverMeiTuan(BigDecimal.ZERO);
            todayStatsStoreVo.setActivityTurnover(BigDecimal.ZERO);
            todayStatsStoreVo.setScanCodePayTotalTurnover(BigDecimal.ZERO);
            todayStatsStoreVo.setTurnoverOnLine(BigDecimal.ZERO);
            todayStatsStoreVo.setTurnoverOfflineCollectionCode(BigDecimal.ZERO);
            try {
                // 不包含当天时间
                if (!DateTimeUtils.getCurrTime().equals(statsStoreDto.getEndDateStr())) {
                    log.info("不调用实时查询数据");
                    return todayStatsStoreVo;
                }

                // 组装查当天的条件参数
                StatsStoreDto conditionStatsStoreDto = new StatsStoreDto();
                conditionStatsStoreDto.setStartTime(DateTimeUtils.getTodayStartTime());
                conditionStatsStoreDto.setEndTime(DateTimeUtils.getTodayEndTime());
                conditionStatsStoreDto.setMchStoreId(statsStoreDto.getMchStoreId());
                conditionStatsStoreDto.setUserInfo(statsStoreDto.getUserInfo());
                conditionStatsStoreDto.setDeviceNo(statsStoreDto.getDeviceNo());
                if (BranchIdEnum.CASH_INCOME.getId().compareTo(statsStoreDto.getBranchId()) == 0) {
                    // 现金
                    StatsStoreVo cashMoneyStatsStoreVo = statsStoreDao.findOrderStatisticsByStoreId(conditionStatsStoreDto);
                    // 保存现金总数
                    todayStatsStoreVo.setCashMoney(cashMoneyStatsStoreVo.getCashMoney());
                    // 吧台现金总数
                    todayStatsStoreVo.setManualTerminalCash(cashMoneyStatsStoreVo.getManualTerminalCash());
                    //超级兑币机现金总数
                    todayStatsStoreVo.setSelfServiceTerminalCash(cashMoneyStatsStoreVo.getSelfServiceTerminalCash());
                } else if (BranchIdEnum.ONLINE_REVENUE.getId().compareTo(statsStoreDto.getBranchId()) == 0) {
                    // 扫码支付
                    StatsStoreVo onlineStatsUserVo = statsStoreDao.findOrderStatisticsByStoreId(conditionStatsStoreDto);
                    todayStatsStoreVo.setTurnoverOnLine(onlineStatsUserVo.getTurnoverOnLine());
                    todayStatsStoreVo.setScanCodePayTotalTurnover(todayStatsStoreVo.getTurnoverOnLine().add(onlineStatsUserVo.getTurnoverOfflineCollectionCode()));
                    todayStatsStoreVo.setTurnoverOfflineCollectionCode(onlineStatsUserVo.getTurnoverOfflineCollectionCode());
                } else if (BranchIdEnum.ACTIVITY_REVENUE.getId().compareTo(statsStoreDto.getBranchId()) == 0) {
                    // 活动收入
                    StatsStoreVo activityStatsStoreVo = statsStoreDao.findActivityMoneyByStoreId(conditionStatsStoreDto);
                    //未核销
                    todayStatsStoreVo.setActivityUnwrittenMoney(activityStatsStoreVo.getActivityUnwrittenMoney());
                    //总金额
                    todayStatsStoreVo.setActivityTurnover(activityStatsStoreVo.getActivityTurnover());
                } else if (BranchIdEnum.DOU_YIN.getId().compareTo(statsStoreDto.getBranchId()) == 0) {
                    //抖音核销收入
                    StatsStoreVo onlineStatsUserVo = statsStoreDao.findOrderStatisticsByStoreId(conditionStatsStoreDto);
                    todayStatsStoreVo.setTurnoverDouYin(onlineStatsUserVo.getTurnoverDouYin());
                }else if (BranchIdEnum.MEI_TUAN.getId().compareTo(statsStoreDto.getBranchId()) == 0) {
                    //美团核销收入
                    StatsStoreVo storeVo = statsStoreDao.findOrderStatisticsByStoreId(conditionStatsStoreDto);
                    todayStatsStoreVo.setTurnoverMeiTuan(storeVo.getTurnoverMeiTuan());
                }else {
                    throw new RuntimeException("分支不存在");
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                return todayStatsStoreVo;
            }
        }, executor);

        CompletableFuture<StatsStoreVo> otherDateFuture = CompletableFuture.supplyAsync(() -> {
            StatsStoreVo otherStatsStoreVo;
            try {
                StatsStoreDto storeDto = new StatsStoreDto();
                storeDto.setStatsType(StatsTypeEnum.statsUser.getCode());
                storeDto.setType(StatisticsTypeEnum.DAY.getCode());
                storeDto.setStartTime(statsStoreDto.getStartDateStr());
                storeDto.setEndTime(statsStoreDto.getEndDateStr());
                storeDto.setUserInfo(statsStoreDto.getUserInfo());
                storeDto.setMchStoreId(statsStoreDto.getMchStoreId());
                storeDto.setDeviceNo(statsStoreDto.getDeviceNo());
                //设备统计 stats_device表
                if(StatsTypeEnum.onDeviceStatsUser.getCode().compareTo(statsStoreDto.getStatsType()) == 0){
                    storeDto.setDeviceNo(statsStoreDto.getDeviceNo());
                    otherStatsStoreVo = statsDeviceService.findStatsStoreByDeviceNo(storeDto);
                }else{
                    otherStatsStoreVo = statsStoreService.findStatsStoreByStoreId(storeDto);
                }
                otherStatsStoreVo.setActivityTurnover(otherStatsStoreVo.getSeckillMoney()
                        .add(otherStatsStoreVo.getGroupBookingMoney())
                        .add(otherStatsStoreVo.getConsumptionOfRedEnvelopesMoney())
                        .add(otherStatsStoreVo.getMemberOfTheStoredValueMoney()));
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e.getMessage());
            }
            return otherStatsStoreVo;
        }, executor);

        CompletableFuture.allOf(todayFuture, otherDateFuture).get();

        StatsStoreVo todayStatsStoreVo = todayFuture.get();
        StatsStoreVo otherDateStatsStoreVo = otherDateFuture.get();
        //只包含了当天
        if (StringUtils.isEmpty(otherDateStatsStoreVo)) {
            return ServerResponse.createBySuccess(todayStatsStoreVo);
        }
        //线上扫码
        todayStatsStoreVo.setTurnoverOnLine(todayStatsStoreVo.getTurnoverOnLine().add(otherDateStatsStoreVo.getTurnoverOnLine()));
        //线下扫码
        todayStatsStoreVo.setTurnoverOfflineCollectionCode(todayStatsStoreVo.getTurnoverOfflineCollectionCode().add(otherDateStatsStoreVo.getTurnoverOfflineCollectionCode()));
        //扫码支付 =  线上扫码 + 线下扫码
        todayStatsStoreVo.setScanCodePayTotalTurnover(todayStatsStoreVo.getTurnoverOnLine().add(todayStatsStoreVo.getTurnoverOfflineCollectionCode()));
        //抖音核销收入
        todayStatsStoreVo.setTurnoverDouYin(todayStatsStoreVo.getTurnoverDouYin().add(otherDateStatsStoreVo.getTurnoverDouYin()));
        //美团核销收入
        todayStatsStoreVo.setTurnoverMeiTuan(todayStatsStoreVo.getTurnoverMeiTuan().add(otherDateStatsStoreVo.getTurnoverMeiTuan()));
        //活动营业额
        todayStatsStoreVo.setActivityTurnover(todayStatsStoreVo.getActivityTurnover().add(otherDateStatsStoreVo.getActivityTurnover()));
        //现金营业额
        todayStatsStoreVo.setCashMoney(todayStatsStoreVo.getCashMoney().add(otherDateStatsStoreVo.getCashMoney()));
        return ServerResponse.createBySuccess(todayStatsStoreVo);
    }

    private ServerResponse commonCheck(StatsStoreDto statsStoreDto) {
        if (StringUtils.isEmpty(statsStoreDto.getBranchId())) {
            return ServerResponse.createByErrorMessage("分支统计ID不能为空");
        }

        if (StringUtils.isEmpty(statsStoreDto.getStartDateStr())) {
            return ServerResponse.createByErrorMessage("开始时间不能为空");
        }

        if (StringUtils.isEmpty(statsStoreDto.getEndDateStr())) {
            return ServerResponse.createByErrorMessage("结束时间不能为空");
        }
        if (StringUtils.isEmpty(statsStoreDto.getMchStoreId())) {
            return ServerResponse.createByErrorMessage("场地ID不能为空");
        }
        if(StringUtils.isEmpty(statsStoreDto.getStatsType())) {
            return ServerResponse.createByErrorMessage("统计分支不能为空");
        }
        if(StatsTypeEnum.onDeviceStatsUser.getCode().compareTo(statsStoreDto.getStatsType()) == 0){
            if(StringUtils.isEmpty(statsStoreDto.getDeviceNo())) {
                return ServerResponse.createByErrorMessage("设备号不能为空");
            }
        }
        return ServerResponse.createBySuccess();
    }
    @Override
    public ServerResponse findStatsStoreBranchData(StatsStoreDto statsStoreDto) {
        final ServerResponse serverResponse = this.commonCheck(statsStoreDto);
        if(!serverResponse.getIsSuccess()){
            return serverResponse;
        }
        PageHelper.startPage(statsStoreDto.getPageNum(), statsStoreDto.getPageSize());
        // 封装现金、线上收益条件参数
        OrderDto orderDto = new OrderDto();
        String startTime = DateTimeUtils.parseLocalDate(statsStoreDto.getStartDateStr()).format(DateTimeUtils.START_DATETIME_FORMATTER);
        String endTime = DateTimeUtils.parseLocalDate(statsStoreDto.getEndDateStr()).format(DateTimeUtils.END_DATETIME_FORMATTER);
        orderDto.setUserInfo(statsStoreDto.getUserInfo());
        orderDto.setStartTime(startTime);
        orderDto.setEndTime(endTime);
        orderDto.setMerchantStoreId(statsStoreDto.getMchStoreId());
        orderDto.setDeviceNo(statsStoreDto.getDeviceNo());
        PageInfo pagResult;
        if (BranchIdEnum.CASH_INCOME.getId().compareTo(statsStoreDto.getBranchId()) == 0) {
            // 现金
            orderDto.setMchType(MchTypeEnum.CASH_RECEIPTS.getCode());
            List<OrderVo> orderVoList = orderService.findOrderStoreListByBranch(orderDto);
            pagResult = new PageInfo(orderVoList);
        } else if (BranchIdEnum.ONLINE_REVENUE.getId().compareTo(statsStoreDto.getBranchId()) == 0) {
            // 扫码支付 = 线上支付 + 线下扫码
            List<OrderVo> orderVoList = orderService.findOrderStoreListByBranchScanCode(orderDto);
            pagResult = new PageInfo(orderVoList);
        }else if (BranchIdEnum.DOU_YIN.getId().compareTo(statsStoreDto.getBranchId()) == 0){
            //抖音核销套餐详情
            orderDto.setMchType(MchTypeEnum.DOUYIN_GROUP_PURCHASE.getCode());
            List<OrderVo> orderVoList = orderService.findOrderStoreListByBranch(orderDto);
            pagResult = new PageInfo(orderVoList);
        }else if (BranchIdEnum.MEI_TUAN.getId().compareTo(statsStoreDto.getBranchId()) == 0){
            //美团核销套餐详情
            orderDto.setMchType(MchTypeEnum.MEITUAN_GROUP_PURCHASE.getCode());
            List<OrderVo> orderVoList = orderService.findOrderStoreListByBranch(orderDto);
            pagResult = new PageInfo(orderVoList);
        }else {
            throw new RuntimeException("分支ID暂无统计");
        }
        return ServerResponse.createBySuccess(pagResult);
    }

}
